设计模式之创建型模式

1. 简单工厂模式( Simple Factory Pattern )

又称为静态工厂方法(Static Factory Method)模式

定义

可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。

结构

Factory:工厂角色
Product:抽象产品角色(父类)
ConcreteProduct:具体产品角色

image

优点

  • 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可
  • 引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类

缺点

  • 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。
  • 工厂角色无法形成基于继承的等级结构。

适用

  • 工厂类负责创建的对象比较少
  • 客户端只知道传入工厂类的参数,对于如何创建对象不关心

2. 工厂方法模式(Factory Method Pattern)

虚拟构造器(Virtual Constructor)模式或者多态工厂(Polymorphic Factory)模式

定义

在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象

结构

Product:抽象产品
ConcreteProduct:具体产品
Factory:抽象工厂
ConcreteFactory:具体工厂

image

优点

  • 用户只需要关心所需产品对应的工厂,无须关心创建细节
  • 加入新产品时,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就可以了

缺点

  • 在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类
  • 需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度

适用

  • 一个类不知道它所需要的对象的类
  • 一个类通过其子类来指定创建哪个对象
  • 将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无须关心是哪一个工厂子类创建产品子类,需要时再动态指定。

拓展

  • 使用多个工厂方法
  • 产品对象的重复使用
  • 多态性的丧失和模式的退化:工厂对象应当有一个抽象的父类型,如果工厂等级结构中只有一个具体工厂类的话,抽象工厂就可以省略,也将发生了退化。当只有一个具体工厂,在具体工厂中可以创建所有的产品对象,并且工厂方法设计为静态方法时,工厂方法模式就退化成简单工厂模式。

3. 抽象工厂模式(Abstract Factory)

提供一个创建产品的接口来负责创建相关或依赖的对象,而不具体明确指定具体类
工厂方法模式针对的是一个产品等级结构,而抽象工厂模式则需要面对多个产品等级结构

定义

提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类

结构

AbstractFactory:抽象工厂
ConcreteFactory:具体工厂
AbstractProduct:抽象产品
Product:具体产品

image

优点

  • 抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建。
  • 增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。

缺点

  • 在添加新的产品对象时,难以扩展抽象工厂来生产新种类的产品,这是因为在抽象工厂角色中规定了所有可能被创建的产品集合,要支持新种类的产品就意味着要对该接口进行扩展,而这将涉及到对抽象工厂角色及其所有子类的修改
  • 开闭原则的倾斜性(增加新的工厂和产品族容易,增加新的产品等级结构麻烦)。

适用

  • 系统中有多于一个的产品族,而每次只使用其中某一产品族。
  • 系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。

拓展

工厂模式的退化:当抽象工厂模式中每一个具体工厂类只创建一个产品对象,也就是只存在一个产品等级结构时,抽象工厂模式退化成工厂方法模式;当工厂方法模式中抽象工厂与具体工厂合并,提供一个统一的工厂来创建产品对象,并将创建对象的工厂方法设计为静态方法时,工厂方法模式退化成简单工厂模式。

4. 建造者模式(Builder Pattern)

定义

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
建造者模式是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。

结构

Builder:抽象建造者
ConcreteBuilder:具体建造者
Director:指挥者
Product:产品角色

image

优点

  • 客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
  • 用户使用不同的具体建造者即可得到不同的产品对象。
  • 可以更加精细地控制产品的创建过程 。
  • 增加新的具体建造者无须修改原有类库的代码,指挥者类针对抽象建造者类编程,系统扩展方便,符合“开闭原则”。

缺点

  • 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。
  • 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。

适用

  • 需要生成的产品对象有复杂的内部结构,这些产品对象通常包含多个成员属性。
  • 需要生成的产品对象的属性相互依赖,需要指定其生成顺序。
  • 对象的创建过程独立于创建该对象的类。在建造者模式中引入了指挥者类,将创建过程封装在指挥者类中,而不在建造者类中。
  • 隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品。

拓展

  • 建造者模式的简化:
    省略抽象建造者角色:如果系统中只需要一个具体建造者的话,可以省略掉抽象建造者。
    省略指挥者角色:在具体建造者只有一个的情况下,如果抽象建造者角色已经被省略掉,那么还可以省略指挥者角色,让
    Builder角色扮演指挥者与建造者双重角色。

  • 建造者模式与抽象工厂模式的比较:
    与抽象工厂模式相比, 建造者模式返回一个组装好的完整产品 ,而 抽象工厂模式返回一系列相关的产品,这些产品位于不同的产品等级结构,构成了一个产品族。
    在抽象工厂模式中,客户端实例化工厂类,然后调用工厂方法获取所需产品对象,而在建造者模式中,客户端可以不直接调用建造者的相关方法,而是通过指挥者类来指导如何生成对象,包括对象的组装过程和建造步骤,它侧重于一步步构造一个复杂对象,返回一个完整的对象。
    如果将抽象工厂模式看成 汽车配件生产工厂 ,生产一个产品族的产品,那么建造者模式就是一个 汽车组装工厂 ,通过对部件的组装可以返回一辆完整的汽车。

5.单例模式

没啥好说的 略

参考

这个写的比较清楚,例子也不错
https://design-patterns.readthedocs.io/zh_CN/latest/index.html

但是这个网页一共只介绍了16种设计模式,故还参考了这几个页面,书到底只是看了下原理,代码还是在电脑上看的舒服啊(:з」∠)
https://www.cnblogs.com/zhili/category/496417.html
https://www.cnblogs.com/ywqu/tag/C%23%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/