简单工厂模式
2020-10-16 本文已影响0人
钉某人
简单工厂.png
RuleConfigParserFactory:负责创建所有parser对象的工厂类,工厂类直接被外界调用,创建所需的对象。
IRuleConfigParser:需要创建对象的抽象接口,声明公共的方法
JsonRuleConfigParser:对象的具体实现类,实现IRuleConfigParser声明的公共方法。
业务场景
根据配置文件的后缀(json、xml、yaml、properties),选择不同的解析器(JsonRuleConfigParser、XmlRuleConfigParser……),
将存储在文件中的配置解析成内存对象 RuleConfig。
IRuleConfigParser
针对规则配置解释器的抽象接口,声明解释器需要实现的功能。
/**
*
* 针对规则配置的解析器:基于接口IRuleConfigParser
*/
public interface IRuleConfigParser {
RuleConfig parse(String configFormat);
}
JsonRuleConfigParser
实现接口IRuleConfigParser,是规则配置解释器的具体实现
public class JsonRuleConfigParser implements IRuleConfigParser {
@Override
public RuleConfig parse(String configFormat) {
return null;
}
}
RuleConfigParserFactory
工厂类,负责创建对应的解释器对象
/**
* 工厂类:负责创建对应的解释器对象
*/
public class RuleConfigParserFactory_1 {
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;
}
}
RuleConfigSource
调用者
/**
* 调用者
*/
public class RuleConfigSource {
public RuleConfig load(String ruleConfigFilePath) {
String ruleConfigFileExtension = getFileExtension(ruleConfigFilePath);
IRuleConfigParser parser = RuleConfigParserFactory_1.createParser(ruleConfigFileExtension);
if (parser == null) {
throw new IllegalArgumentException("Rule config file format is not supported: " + ruleConfigFilePath);
}
/*
伪代码:读取配置文件中的内容并赋值给configContent字段
*/
String configContent = "";
RuleConfig ruleConfig = parser.parse(configContent);
return ruleConfig;
}
/**
* 获取文件的扩展名
*
* @param ruleConfigFilePath
* @return
*/
private String getFileExtension(String ruleConfigFilePath) {
String extension = "";
/*
这里是解析文件名获取扩展名的代码逻辑
*/
return extension;
}
}
简单工厂模式还有另一种实现方式:将parser事先创建好,缓存起来,使用时从缓存中取出直接使用。
public class RuleConfigParserFactory {
private static final Map<String,IRuleConfigParser> cachedParsers = new HashMap<>();
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 (null == configFormat || configFormat.isEmpty()){
return null;
}
IRuleConfigParser parser = cachedParsers.get(configFormat.toLowerCase());
return parser;
}
}
尽管简单工厂模式的代码实现中,有多处 if 分支判断逻辑,违背开闭原则,但权衡扩展性和可读性,这样的代码实现在大多数情况下(比如,不需要频繁地添加 parser,也没有太多的 parser)是没有问题的