简单工厂(Simple Factory)
public class RuleConfigSource {
public RuleConfig load(
String ruleConfigFilePath) {
String ruleConfigFileExtension =getFileExtension(ruleConfigFilePath);
IRuleConfigParser parser = null;
if ("json".equalsIgnoreCase(ruleConfigFileExtension)) {
parser = new JsonRuleConfigParser();
} else if ("xml".equalsIgnoreCase(ruleConfigFileExtension)) {
parser = new XmlRuleConfigParser();
} else if ("yaml".equalsIgnoreCase(ruleConfigFileExtension)) { parser = new YamlRuleConfigParser();
} else if ("properties".equalsIgnoreCase(ruleConfigFileExtension)) { parser = new PropertiesRuleConfigParser();
} else { throw new InvalidRuleConfigException( "Rule config file format is not supported: " + ruleConfigFilePath) }
String configText = "";
//从ruleConfigFilePath文件中读取配置文本到configText中
RuleConfig ruleConfig = parser.parse(configText);
return ruleConfig; }
private String getFileExtension(String filePath) {
//...解析文件名获取扩展名,比如rule.json,返回json return "json";
}
}
我们可以将代码中涉及 parser 创建的部分逻辑剥离出来,抽象成 createParser() 函数。
重构之后的代码如下所示:
public RuleConfig load(String ruleConfigFilePath) {
String ruleConfigFileExtension = getFileExtension(ruleConfigFilePath); IRuleConfigParser parser = createParser(ruleConfigFileExtension);
if (parser == null) {
throw new InvalidRuleConfigException( "Rule config file format is not supported: " + ruleConfigFilePath }
String configText = "";
//从ruleConfigFilePath文件中读取配置文本到configText中
RuleConfig ruleConfig = parser.parse(configText);
return ruleConfig; }
private String getFileExtension(String filePath) {
//...解析文件名获取扩展名,比如rule.json,返回json return "json";
}
private IRuleConfigParser createParser(String configFormat) { IRuleConfigParser parser = null;
if ("json".equalsIgnoreCase(configFormat)) {
parser = new JsonRuleConfigParser();
} else if ("xml".equalsIgnoreCase(configFormat)) {
parser = new XmlRuleConfigParser();
} else if ("yaml".equalsIgnoreCase(configFormat)) {
parser = new YamlRuleConfigParser();
} else if ("properties".equalsIgnoreCase(configFormat)) {
parser = new PropertiesRuleConfigParser();
}
return parser;
}
}
为了让类的职责更加单一、代码更加清晰,我们还可以进一步将 createParser() 函数剥离 到一个独立的类中,让这个类只负责对象的创建。而这个类就是我们现在要讲的简单工厂模 式类。
public class RuleConfigSource {
public RuleConfig load(String ruleConfigFilePath) {
String ruleConfigFileExtension = getFileExtension(ruleConfigFilePath); IRuleConfigParser parser =RuleConfigParserFactory.createParser(ruleConfig)
if (parser == null) {
throw new InvalidRuleConfigException( "Rule config file format is not supported: " + ruleConfigFilePath }
String configText = "";
//从ruleConfigFilePath文件中读取配置文本到configText中
RuleConfig ruleConfig = parser.parse(configText);
return ruleConfig; }
private String getFileExtension(String filePath) {
//...解析文件名获取扩展名,比如rule.json,返回json return "json";
} }
public class RuleConfigParserFactory {
public static IRuleConfigParser createParser(String configFormat) { IRuleConfigParser parser = null;
if ("json".equalsIgnoreCase(configFormat)) {
parser = new JsonRuleConfigParser();
} else if ("xml".equalsIgnoreCase(configFormat)) {
parser = new XmlRuleConfigParser();
} else if ("yaml".equalsIgnoreCase(configFormat)) {
parser = new YamlRuleConfigParser();
} else if ("properties".equalsIgnoreCase(configFormat)) {
parser = new PropertiesRuleConfigParser();
}
return parser;
}
}
另外我们可以将 parser 事先创建好缓存起来。当调用 createParser() 函数的时候,我 们从缓存中取出 parser 对象直接使用。
public class RuleConfigParserFactory {
private static final Map cachedParsers = new HashMa static { cachedParsers.put("json", new JsonRuleConfigParser()); cachedParsers.put("xml", new XmlRuleConfigParser()); cachedParsers.put("yaml", new YamlRuleConfigParser()); cachedParsers.put("properties", new PropertiesRuleConfigParser());
}
public static IRuleConfigParser createParser(String configFormat) {
if (configFormat == null || configFormat.isEmpty()) {
return null;
//返回null还是IllegalArgumentException全凭你自己说了算
}
IRuleConfigParser parser = cachedParsers.get(configFormat.toLowerCase()); return parser; } }
工厂方法(Factory Method)
要将 if 分支逻辑去掉,比较经典处理方法就是利用多态。
public interface IRuleConfigParserFactory {
IRuleConfigParser createParser();
}
public class JsonRuleConfigParserFactory implements IRuleConfigParserFactory {
@Override public IRuleConfigParser createParser() {
return new JsonRuleConfigParser();
}
}
public class XmlRuleConfigParserFactory implements IRuleConfigParserFactory {
@Override public IRuleConfigParser createParser() {
return new XmlRuleConfigParser();
}
}
public class YamlRuleConfigParserFactory implements IRuleConfigParserFactory {
@Override
public IRuleConfigParser createParser() {
return new YamlRuleConfigParser();
}
}
public class PropertiesRuleConfigParserFactory implements IRuleConfigParserFact{
@Override
public IRuleConfigParser createParser() {
return new PropertiesRuleConfigParser();
}
}
工厂方法模式比起简单工厂模式更加符合开闭原则。
public class RuleConfigSource {
public RuleConfig load(String ruleConfigFilePath) {
String ruleConfigFileExtension = getFileExtension(ruleConfigFilePath); IRuleConfigParserFactory parserFactory = null;
if ("json".equalsIgnoreCase(ruleConfigFileExtension)) {
parserFactory = new JsonRuleConfigParserFactory();
} else if ("xml".equalsIgnoreCase(ruleConfigFileExtension)) { parserFactory = new XmlRuleConfigParserFactory();
} else if ("yaml".equalsIgnoreCase(ruleConfigFileExtension)) { parserFactory = new YamlRuleConfigParserFactory();
} else if ("properties".equalsIgnoreCase(ruleConfigFileExtension)) { parserFactory = new PropertiesRuleConfigParserFactory();
} else {
throw new InvalidRuleConfigException("Rule config file format is not supp } IRuleConfigParser parser = parserFactory.createParser(); String configText = "";
//从ruleConfigFilePath文件中读取配置文本到configText中
RuleConfig ruleConfig = parser.parse(configText);
return ruleConfig; }
private String getFileExtension(String filePath) {
//...解析文件名获取扩展名,比如rule.json,返回json return "json";
}
}
工厂类对象的创建逻辑又耦合进了 load() 函数中,我们可以为工厂类再创建一个简单工厂,也就是工厂的工厂,用来创建工厂类对象。
RuleConfigParserFactoryMap
类是创建工厂对象的工厂类,getParserFactory()
返回的 是缓存好的单例工厂对象。
public class RuleConfigSource {
public RuleConfig load(String ruleConfigFilePath) {
String ruleConfigFileExtension = getFileExtension(ruleConfigFilePath); IRuleConfigParserFactory parserFactory = RuleConfigParserFactoryMap.getPars
if (parserFactory == null) {
throw new InvalidRuleConfigException("Rule config file format is not supp
}
IRuleConfigParser parser = parserFactory.createParser();
String configText = "";
//从ruleConfigFilePath文件中读取配置文本到configText中
RuleConfig ruleConfig = parser.parse(configText);
return ruleConfig; }
private String getFileExtension(String filePath) {
//...解析文件名获取扩展名,比如rule.json,返回json return "json";
}
}
//因为工厂类只包含方法,不包含成员变量,完全可以复用,
//不需要每次都创建新的工厂类对象,所以,简单工厂模式的第二种实现思路更加合适。
public class RuleConfigParserFactoryMap {
//工厂的工厂
private static final Map cachedFactories = static { cachedFactories.put("json", new JsonRuleConfigParserFactory()); cachedFactories.put("xml", new XmlRuleConfigParserFactory()); cachedFactories.put("yaml", new YamlRuleConfigParserFactory()); cachedFactories.put("properties", new PropertiesRuleConfigParserFactory()) }
public static IRuleConfigParserFactory getParserFactory(String type) { if (type == null || type.isEmpty())
{ return null;
}
IRuleConfigParserFactory parserFactory = cachedFactories.get(type.toLowerCa return parserFactory; } }
那什么时候该用工厂方法模式,而非简单工厂模式呢?
要组合其他类对象,做各种初始化操作的时候,我们推荐使用工厂方法模式,将复杂的创建逻 辑拆分到多个工厂类中,让每个工厂类都不至于过于复杂。
抽象工厂(Abstract Factory)
针对规则配置的解析器:基于接口
IRuleConfigParser
JsonRuleConfigParser
XmlRuleConfigParser
YamlRuleConfigParser
PropertiesRuleConfigParser
针对系统配置的解析器:
基于接口
ISystemConfigParser
JsonSystemConfigParser
XmlSystemConfigParser
YamlSystemConfigParser
PropertiesSystemConfigParser
我们可以让一个工厂负责创建多个不同类 型的对象(IRuleConfigParser、ISystemConfigParser 等),而不是只创建一种 parser 对象。这样就可以有效地减少工厂类的个数。
public interface IConfigParserFactory {
IRuleConfigParser createRuleParser();
ISystemConfigParser createSystemParser();
//此处可以扩展新的parser类型,比如IBizConfigParser
}
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代码