简单工厂:包含判断什么对象的逻辑
工厂方法模式:调用者判断要实例化什么具体类型的工厂,进而创建出想要的对象
一、简单工厂
适用场景:
不足:
常规实现:单独的工厂类,负责创建,通常方法createXXX,也可其他命名
存在两种实现方式
1、常规实现
1 public class RuleConfigParserFactory { 2 public static IRuleConfigParser createParser(String configFormat) { 3 IRuleConfigParser parser = null; 4 if ("json".equalsIgnoreCase(configFormat)) { 5 parser = new JsonRuleConfigParser(); 6 } else if ("xml".equalsIgnoreCase(configFormat)) { 7 parser = new XmlRuleConfigParser(); 8 } else if ("yaml".equalsIgnoreCase(configFormat)) { 9 parser = new YamlRuleConfigParser(); 10 } else if ("properties".equalsIgnoreCase(configFormat)) { 11 parser = new PropertiesRuleConfigParser(); 12 } 13 return parser; 14 } 15 }
2、优化实现:类似单例+简单工厂,提前创建好对象缓存
public class RuleConfigParserFactory { private static final Map<String, RuleConfigParser> 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 (configFormat == null || configFormat.isEmpty()) { return null;//返回null还是IllegalArgumentException全凭你自己说了算 } IRuleConfigParser parser = cachedParsers.get(configFormat.toLowerCase()); return parser; } }
二、工厂方法:
适用场景:
不足:
常规实现:
1 public interface IRuleConfigParserFactory { 2 IRuleConfigParser createParser(); 3 } 4 5 public class JsonRuleConfigParserFactory implements IRuleConfigParserFactory { 6 @Override 7 public IRuleConfigParser createParser() { 8 return new JsonRuleConfigParser(); 9 } 10 } 11 12 public class XmlRuleConfigParserFactory implements IRuleConfigParserFactory { 13 @Override 14 public IRuleConfigParser createParser() { 15 return new XmlRuleConfigParser(); 16 } 17 } 18 // 工厂方法使用,变更需要修改load(),导致设计更复杂 19 public class RuleConfigSource { 20 public RuleConfig load(String ruleConfigFilePath) { 21 String ruleConfigFileExtension = getFileExtension(ruleConfigFilePath); 22 23 IRuleConfigParserFactory parserFactory = null; 24 if ("json".equalsIgnoreCase(ruleConfigFileExtension)) { 25 parserFactory = new JsonRuleConfigParserFactory(); 26 } else if ("xml".equalsIgnoreCase(ruleConfigFileExtension)) { 27 parserFactory = new XmlRuleConfigParserFactory();
优化实现:增加工厂的工厂
1 public class RuleConfigSource { 2 public RuleConfig load(String ruleConfigFilePath) { 3 String ruleConfigFileExtension = getFileExtension(ruleConfigFilePath); 4 5 IRuleConfigParserFactory parserFactory = RuleConfigParserFactoryMap.getParserFactory(ruleConfigFileExtension); 6 if (parserFactory == null) { 7 throw new InvalidRuleConfigException("Rule config file format is not supported: " + ruleConfigFilePath); 8 } 9 IRuleConfigParser parser = parserFactory.createParser(); 10 11 String configText = ""; 12 //从ruleConfigFilePath文件中读取配置文本到configText中 13 RuleConfig ruleConfig = parser.parse(configText); 14 return ruleConfig; 15 } 16 17 private String getFileExtension(String filePath) { 18 //...解析文件名获取扩展名,比如rule.json,返回json 19 return "json"; 20 } 21 } 22 23 //因为工厂类只包含方法,不包含成员变量,完全可以复用, 24 //不需要每次都创建新的工厂类对象,所以,简单工厂模式的第二种实现思路更加合适。 25 public class RuleConfigParserFactoryMap { //工厂的工厂 26 private static final Map<String, IRuleConfigParserFactory> cachedFactories = new HashMap<>(); 27 28 static { 29 cachedFactories.put("json", new JsonRuleConfigParserFactory()); 30 cachedFactories.put("xml", new XmlRuleConfigParserFactory()); 31 cachedFactories.put("yaml", new YamlRuleConfigParserFactory()); 32 cachedFactories.put("properties", new PropertiesRuleConfigParserFactory()); 33 } 34 35 public static IRuleConfigParserFactory getParserFactory(String type) { 36 if (type == null || type.isEmpty()) { 37 return null; 38 } 39 IRuleConfigParserFactory parserFactory = cachedFactories.get(type.toLowerCase()); 40 return parserFactory; 41 } 42 }