简单工厂模式
/**
* @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代码