【创建型】简单工厂、工厂方法、抽象工厂

 

简单工厂:包含判断什么对象的逻辑

工厂方法模式:调用者判断要实例化什么具体类型的工厂,进而创建出想要的对象

 

一、简单工厂

适用场景:

不足:

常规实现:单独的工厂类,负责创建,通常方法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 }

 

上一篇:实验5:开源控制器实践——POX


下一篇:2021SC@SDUSC山东大学软件学院软件工程应用与实践——yolov5代码分析——第五篇——train.py(1)