九折技术 九折技术
首页
  • Go
  • MIT-6824
  • 算法与数据结构
  • 面向对象
  • 代码整洁
  • 重构
  • 设计模式
  • 学习
  • 技术
  • 人文
关于
  • 网站
  • 资源
  • 分类
  • 标签
  • 归档
GitHub

HoldDie

长期有耐心,一切才刚刚开始!
首页
  • Go
  • MIT-6824
  • 算法与数据结构
  • 面向对象
  • 代码整洁
  • 重构
  • 设计模式
  • 学习
  • 技术
  • 人文
关于
  • 网站
  • 资源
  • 分类
  • 标签
  • 归档
GitHub
  • 代码整洁

  • 重构

  • 设计模式

    • 创建型-单例模式
    • 创建型-工厂模式
      • 创建型-建造者模式
      • 创建型-原型模式
      • 结构型-代理模式
      • 结构型-桥接模式
      • 结构型-装饰器模式
      • 结构型-适配器模式
      • 结构型-门面模式
      • 结构型-组合模式
      • 结构型-享元模式
      • 行为型-观察者模式
      • 行为型-模板模式
      • 行为型-策略模式
      • 行为型-责任链模式
      • 行为型-状态模式
      • 行为型-迭代器模式
      • 行为型-访问者模式
      • 行为型-备忘录模式
      • 行为型-命令模式
      • 行为型-解释器模式
      • 行为型-中介模式
    • 架构
    • 设计模式
    holddie
    2020-08-28

    创建型-工厂模式

    # 简单工厂(Simple Factory)

    • 应用多态或设计模式来替代 if 分支判断逻辑,也并不是没有任何缺点的,它虽然提高了代码的扩展性,更加符合开闭原则,但也增加了类的个数,牺牲了代码的可读性。
    • 简单工厂模式看作是工厂方法模式的一种特例。
    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";
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28

    # 工厂方法

    • 工厂方法模式比起简单工厂模式更加符合开闭原则。
    • 为工厂类再创建一个简单工厂,也就是工厂的工厂,用来创建工厂类对象。
    • 基于这个设计思想,当对象的创建逻辑比较复杂,不只是简单的 new 一下就可以,而是要组合其他类对象,做各种初始化操作的时候,我们推荐使用工厂方法模式。
    • 将复杂的创建逻辑拆分到多个工厂类中,让每个工厂类都不至于过于复杂。
    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 IRuleConfigParserFactory {
      @Override
      public IRuleConfigParser createParser() {
        return new PropertiesRuleConfigParser();
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31

    # 抽象工厂

    • 我们可以让一个工厂负责创建多个不同类型的对象(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代码
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31

    # 对应 UML

    # 工厂设计模式的思考

    # 使用工厂模式的场景

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

    # 简单工厂和工厂方法差异?

    • 工厂方法只会返回一种类型的实例,最好具有父类或者共同实现的接口。
    • 简单工厂:用来生产同一等级结构的任意产品(对于任意新增的产品,无能为力)
    • 工厂方法:用来生产同一等级结构中的固定产品(支持增加任意产品)
    • 抽象工厂:用来生产不同产品族的全部产品。(对于新增的产品,无能为力,只是多种实现定义好的产品生成,实例的组合,支持添加产品族,就是产品的下线由谁生产,但是生产什么是事先固定好的)

    # 工厂方法和抽象工厂差异?

    • 抽象工厂关键在于产品之间的抽象关系,所以至少要两个产品,工厂方法在于生成产品,不关注产品键的关系,所以可以只生成一个产品。
    • 抽象工厂中客户端把产品的抽象关系理清楚,在最终使用的时候,一般使用客户端和(其接口),产品之间的关系是被封装固定的;而工厂方法是在最终使用的时候,使用产品本身。
    • 抽象工厂更像一个复杂版本的策略模式,策略模式通过更换策略来改变处理方式或者结果,而抽象工厂的客户端,通过更改工厂来改变结果,所以在使用的时候,就使用客户端和更换工厂,而看不到产品本身。
    • 工厂方法的目的是生产商品,所以能看到商品,而且还是要使用商品,当然如果产品在创建者内部使用,那么工厂方法就是为了完善创建者,从而可以使用创建者,另外创建者本身是不能更换所生成的产品的。
    • 抽象工厂的工厂是类,工厂方法的工厂是方法。
    编辑
    #工厂模式
    上次更新: 2020/09/08, 15:09:00
    创建型-单例模式
    创建型-建造者模式

    ← 创建型-单例模式 创建型-建造者模式→

    最近更新
    01
    行为型-访问者模式
    11-24
    02
    行为型-备忘录模式
    11-24
    03
    行为型-命令模式
    11-24
    更多文章>
    Theme by Vdoing | Copyright © 2019-2020 HoldDie | MIT License
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式