java设计模式之工厂模式


工厂模式分为简单工厂、工厂方法和抽象工厂,主要用于将复杂对象的创建抽象到一个专门的工厂类中,从而将对象的使用和构建解耦。

我们以一个配置解析的例子来说明一下工厂模式。

比如在java项目中,我们会把一些不经常改变的配置信息(比如数据库连接等),写入配置文件,而配置文件有很多类型,比如json、xml、properties

一、简单工厂

首先,我们使用简单工厂创建解析配置文件的解析器类对象

先定义一个配置类,文件里的内容最终会解析成一个config类

public class Config {
}

多个文件解析器的抽象父类

public abstract class FileParser {
    public abstract Config parse(File file);
}

三个文件解析器

public class JsonParser extends FileParser {
    
    @Override
    public Config parse(File file) {
        //省略具体解析逻辑
        return new Config();
    }
}


public class PropertiesParser extends FileParser {
    
    @Override
    public Config parse(File file) {
        //省略具体解析逻辑
        return new Config();
    }
}

public class XmlParser extends FileParser {
    
    @Override
    public Config parse(File file) {
        //省略具体解析逻辑
        return new Config();
    }
}

解析器工厂类

/**
 * 简单工厂模式
 * 根据不同的配置文件格式创建不同的解析器解析配置文件
 */
public class ConfigParserFactory {
    
    public static FileParser createParser(File file) {
        String fileName = file.getName();
        FileParser fileParser;
        if (fileName.endsWith("json")) {
            fileParser = new JsonParser();
        } else if (fileName.endsWith("xml")) {
            fileParser = new XmlParser();
        } else {
            fileParser = new PropertiesParser();
        }
        return fileParser;
    }

    public static void main(String[] args) {
        File file = new File("D:/tipi/file.json");
        FileParser fileParser = ConfigParserFactory.createParser(file);
        Config config = fileParser.parse(file);
    }
    
}

二、工厂方法

上面的简单工厂没有省略掉if/else,只是将它抽取到了一个专门的工厂类中,如果想彻底省略掉if/else,可以使用工厂方法模式

首先我们定义一个工厂类接口

/**
 * 工厂方法
 * 完全省略了if/else只是增加了不少factory类
 * 每增加一种Parser,只需要新增一个parser类和对应的factory类即可,更加符合开闭原则
 */
public interface ParserFactory {
   FileParser createParser();
}

然后为每个解析器都分别创建一个工厂

public class JsonParserFactory implements ParserFactory {
    @Override
    public FileParser createParser() {
        return new JsonParser();
    }
}

public class PropertiesParserFactory implements ParserFactory {
    @Override
    public FileParser createParser() {
        return new PropertiesParser();
    }
}

public class XmlParserFactory implements ParserFactory {
    @Override
    public FileParser createParser() {
        return new XmlParser();
    }
}

我们使用一个工厂的工厂来生成工厂

public class ConfigParserFactoryMap {
    private final static Map map=new ConcurrentHashMap<>();

    static {
        map.put("json",new JsonParserFactory());
        map.put("xml",new XmlParserFactory());
        map.put("properties",new PropertiesParserFactory());
    }

    public static ParserFactory get(String fileType){
        return map.get(fileType);
    }

    public static void main(String[] args) {
        File file = new File("D:/config/file.xml");
        String name = file.getName();
        ParserFactory parserFactory = ConfigParserFactoryMap.get(name);
        FileParser parser = parserFactory.createParser();
        Config config = parser.parse(file);

    }
}