定义

当创建逻辑比较复杂,就考虑使用工厂模式,封装对象的创建过程,将对象的创建和使用相分离。工厂模式的作用:

  • 封装变化:创建逻辑有可能变化,封装成工厂类之后,创建逻辑的变更对调用者透明。
  • 代码复用:创建代码抽离到独立的工厂类之后可以复用。
  • 隔离复杂性:封装复杂的创建逻辑,调用者无需了解如何创建对象。
  • 控制复杂度:将创建代码抽离出来,让原本的函数或类职责更单一,代码更简洁。


简单工厂(Simple Factory)

结构

  • 简单工厂(SimpleFactory):是简单工厂模式的核心,负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。
  • 抽象产品(Product):是简单工厂创建的所有对象的父类,负责描述所有实例共有的公共接口。
  • 具体产品(ConcreteProduct):是简单工厂模式的创建目标。


工厂模式(Factory Pattern) - 图1

示例

  1. public class RuleConfigParserFactory {
  2. private static final Map<String, RuleConfigParser> cachedParsers = new HashMap<>();
  3. static {
  4. cachedParsers.put("json", new JsonRuleConfigParser());
  5. cachedParsers.put("xml", new XmlRuleConfigParser());
  6. cachedParsers.put("yaml", new YamlRuleConfigParser());
  7. cachedParsers.put("properties", new PropertiesRuleConfigParser());
  8. }
  9. public static IRuleConfigParser createParser(String configFormat) {
  10. if (configFormat == null || configFormat.isEmpty()) {
  11. return null;//返回null还是IllegalArgumentException全凭你自己说了算
  12. }
  13. IRuleConfigParser parser = cachedParsers.get(configFormat.toLowerCase());
  14. return parser;
  15. }
  16. }

简单工厂模式还叫作静态工厂方法模式(Static Factory Method Pattern)。之所以叫静态工厂方法模式,是因为其中创建对象的方法是静态的。

优点

封装创建类的逻辑,实现功能的单一职责。

缺点

当遇到以下情况时,简单工厂模式会违反OCP:

  • 需要根据不同情况生成不同对象
  • 生成各个不同对象的逻辑比较复杂
  • 生成各个不同对象的逻辑可能发生变化

此时,随着时间的推移,我们需要不断地修改简单工厂类,也就违反开闭原则了。

应用

DateFormat.parse DateFormat.format

Calender

String.valueOf

工厂方法(Factory Method)

工厂方法 —- 简单工厂的工厂

结构

  1. 抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法 newProduct() 来创建产品。
  2. 具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
  3. 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。
  4. 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。


工厂模式(Factory Pattern) - 图2

示例

  1. public class RuleConfigParserFactoryMap { //工厂的工厂
  2. private static final Map<String, IRuleConfigParserFactory> cachedFactories = new HashMap<>();
  3. static {
  4. cachedFactories.put("json", new JsonRuleConfigParserFactory());
  5. cachedFactories.put("xml", new XmlRuleConfigParserFactory());
  6. cachedFactories.put("yaml", new YamlRuleConfigParserFactory());
  7. cachedFactories.put("properties", new PropertiesRuleConfigParserFactory());
  8. }
  9. public static IRuleConfigParserFactory getParserFactory(String type) {
  10. if (type == null || type.isEmpty()) {
  11. return null;
  12. }
  13. IRuleConfigParserFactory parserFactory = cachedFactories.get(type.toLowerCase());
  14. return parserFactory;
  15. }
  16. }

优点

工厂方法模式比起简单工厂模式更加符合开闭原则。此处示例无法体现工厂方法的优势是因为各个具体Parser的实现过于简单,只需要new一下即可,但如果各个类的创建行为比较复杂时,工厂方法的优势就体现出来了。

缺点

当创建的类的个数过多时,需要针对每个类都编写一个工厂类。

应用

Spring BeanFactory


抽象工厂(Abstract Factory)

结构

  1. 抽象工厂(Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法 newProduct(),可以创建多个不同等级的产品。
  2. 具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
  3. 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
  4. 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系。

工厂模式(Factory Pattern) - 图3

示例

  1. public interface IConfigParserFactory {
  2. IRuleConfigParser createRuleParser();
  3. ISystemConfigParser createSystemParser();
  4. //此处可以扩展新的parser类型,比如IBizConfigParser
  5. }
  6. public class JsonConfigParserFactory implements IConfigParserFactory {
  7. @Override
  8. public IRuleConfigParser createRuleParser() {
  9. return new JsonRuleConfigParser();
  10. }
  11. @Override
  12. public ISystemConfigParser createSystemParser() {
  13. return new JsonSystemConfigParser();
  14. }
  15. }
  16. public class XmlConfigParserFactory implements IConfigParserFactory {
  17. @Override
  18. public IRuleConfigParser createRuleParser() {
  19. return new XmlRuleConfigParser();
  20. }
  21. @Override
  22. public ISystemConfigParser createSystemParser() {
  23. return new XmlSystemConfigParser();
  24. }
  25. }
  26. // 省略YamlConfigParserFactory和PropertiesConfigParserFactory代码

优点

让一个工厂负责创建多个不同类型的对象,减少工厂类的个数