设计模式-工厂模式

162 阅读3分钟

简单工厂模式

/**
 * @author cuckooYang
 * @create 2020-08-04 15:12
 * @description 简单工厂模式
 **/

public class RuleConfigSource {

    public IRuleConfigParser load(String ruleConfigFilePath) throws Exception {
        String ruleConfigFileExtension = getFileExtension(ruleConfigFilePath);

        return RuleConfigParserFactory.createParser(ruleConfigFileExtension);

    }
    private String getFileExtension(String filePath){
        return "json";
    }
}

/**
 * @author cuckooYang
 * @create 2020-08-04 15:28
 * @description 
 **/

public class RuleConfigParserFactory {
    private static IRuleConfigParser iRuleConfigParser;
    public static IRuleConfigParser createParser(String configFormat) throws Exception {
        if("json".equalsIgnoreCase(configFormat)){
            iRuleConfigParser = new JsonRuleConfigParser();
        }else if("xml".equalsIgnoreCase(configFormat)){
            iRuleConfigParser = new XmlRuleConfigParser();
        }else if("properties".equalsIgnoreCase(configFormat)){
            iRuleConfigParser = new PropertiesRuleConfigParser();
        }else{
            throw new Exception("Rule config file format is not suported"+configFormat);

        }
        return iRuleConfigParser;
    }
}
/**
 * @author cuckooYang
 * @create 2020-08-04 15:34
 * @description 单例模式和简单工厂相结合
 **/

public class RuleConfigParser1Factory {
    private static Map<String,IRuleConfigParser> cacheMap = new HashMap<>();
    static{
        cacheMap.put("json",new JsonRuleConfigParser());
        cacheMap.put("xml",new XmlRuleConfigParser());
        cacheMap.put("properties",new PropertiesRuleConfigParser());
    }
    public static IRuleConfigParser createParser(String configFormat) throws Exception {
        if(configFormat == null || configFormat.isEmpty()){
            return null;
        }
        return cacheMap.get(configFormat);
    }
}

总结一下,虽然简单工厂模式违反了开闭原则,但是权衡可读性和可扩展性,这样的代码只要不是频繁的添加新的parse,是可以接受的

工厂方法模式

public interface IRuleConfigParserFactory{
	IRuleConfigParser createParser();
}
public class JsonRuleConfigParserFactory implements IRuleConfigParserFactory{
	
	public IRuleConfigParser createParser(){
		return new JsonRuleConfigParser();
	}
}
public class XmlRuleConfigParserFactory implements IRuleConfigParserFactory{
	
	public IRuleConfigParser createParser(){
		return new XmlRuleConfigParser();
	}
}
public class PropertiesRuleConfigParserFactory implements IRuleConfigParserFactory{
	
	public IRuleConfigParser createParser(){
		return new PropertiesRuleConfigParser();
	}
}
/**
 * @author cuckooYang
 * @create 2020-08-04 15:12
 * @description 工厂方法模式
 **/

public class RuleConfigSource {
	private IRuleConfigParser iRuleConfigParser;
    public IRuleConfigParser load(String ruleConfigFilePath) throws Exception {
        String ruleConfigFileExtension = getFileExtension(ruleConfigFilePath);

         if("json".equalsIgnoreCase(configFormat)){
            iRuleConfigParser = new JsonRuleConfigParserFactory();
        }else if("xml".equalsIgnoreCase(configFormat)){
            iRuleConfigParser = new XmlRuleConfigParserFactory();
        }else if("properties".equalsIgnoreCase(configFormat)){
            iRuleConfigParser = new PropertiesRuleConfigParserFactory();
        }else{
            throw new Exception("Rule config file format is not suported"+configFormat);

        }
		return iRuleConfigParser;

    }
    private String getFileExtension(String filePath){
        return "json";
    }
}

从上面的代码,我们可以看出,引入了工厂方法模式之后,工厂类的对象耦合进了load()函数中,反而让设计变得更加复杂了。

什么时候该用工厂方法模式,什么时候该用简单工厂模式呢

当我们需要将一个创建对象的逻辑剥离出去,创建一个工厂方法,原因是这个代码块的逻辑过于复杂,但是如果代码逻辑本身不复杂,我们就没有必要进行拆分

当对象创建过程过于复杂的时候,要组合其他的类的时候,推荐使用工厂方法模式

抽象工厂模式

在简单工厂和工厂方法中,类只有一种分类方式。比如,在规则配置解析那个例子中,解析器类只会根据配置文件格式(Json、Xml、Yaml……)来分类。但是,如果类有两种分类方式,比如,我们既可以按照配置文件格式来分类,也可以按照解析的对象(Rule 规则配置还是 System 系统配置)来分类,那就会对应下面这 8 个 parser 类。

针对规则配置的解析器:基于接口IRuleConfigParser
JsonRuleConfigParser
XmlRuleConfigParser
YamlRuleConfigParser
PropertiesRuleConfigParser
针对系统配置的解析器:基于接口ISystemConfigParser
JsonSystemConfigParser
XmlSystemConfigParser
YamlSystemConfigParser
PropertiesSystemConfigParser
public interface IConfigParserFactory {
	IRuleConfigParser createRuleParser();
	ISystemConfigParser createSystemParser();
	//此处可以扩展新的parser类型,比如IBizConfigParser 5 
} 
public class JsonConfigParserFactory implements IConfigParserFactory { 
	@Override
	public IRuleConfigParser createRuleParser() {
		return new JsonRuleConfigParser()
	}
	@Override
	public ISystemConfigParser createSystemParser() {
		return new JsonSystemConfigParser();
	}
}
public class XmlConfigParserFactory implements IConfigParserFactory {
	@Override
	public IRuleConfigParser createRuleParser() {
		return new XmlRuleConfigParser();
	}
	@Override
	public ISystemConfigParser createSystemParser() {
		return new XmlSystemConfigParser();
	}
} 
// 省略YamlConfigParserFactory和PropertiesConfigParserFactory代码