Simple Factory
- 也叫 Static Factory Method 模式
- 根据参数的不同返回不同类的实例
- 被创建的实例通常有共同的 父类
结构
- Factory
- 负责创建所有实例
- Product
- 所有创建对象的父类
- 描述所有实例公共接口
- Concrete Product
- 具体的产品,是Producet的实例
特点
- 工厂类必须含有判断逻辑来决定什么时候创建何种产品类
- 工厂类集中了所有产品创建逻辑,一旦无法工作,整个系统都受影响
- 一定程度增加系统开销
- 工厂方法是静态方法,造成工厂无法形成基于继承的结构
场景
- 工厂类负责创建的对象少
- 客户端只知道传入工厂类的参数,对如何创建对象不关心
Factory Method
- 也叫 工厂模式、虚构造器模式、多态工厂模式
- 工厂父类定义创建产品对象的共有接口,工厂子类负责生产产品对象
- 将产品实例化延迟到子类完成,由子类决定实例化何种产品
结构
- Product
- Concrete Product
- Factory
- Concrete Factory
特点
- 所有的具体工厂都具有同一抽象父类
- 在系统加入新产品时,无需修改抽象的工厂类和抽象的产品接口,只需要添加一个具体的工厂和产品即可
- 扩展性好,完全符合 开闭原则
- 增加系统复杂性,带来额外开销,增加系统理解难度
- 仅返回一个具体产品,会违背工厂的用于,从而退化。同样的,如果只有一个具体工厂,也会退化为简单工厂模式
场景
- 类不需要知道他所需要的对象的类,只要知道对应的工厂即可
- 将创建对象的任务委托给工厂子类中的一个,可以根据需要动态指定_(将工厂类类名存储在配置文件或数据库中)_
Abstract Factory
- 工厂方法模式中,具体的工厂负责审查具体的产品,每个工厂对应一个具体产品,有时候,我们需要一个共产提供多个产品
- 引入两个概念
- 产品等级结构,即产品的继承结构
- 产品族,同一工厂生产的,谓语不同产品等级中的一组产品
- 适用于系统提供的工厂所需生产的不是简单对象,而是位于不同产品结构中不同类型的具体产品
- 与工厂方法模式相比,最大区别在于其针对一个产品等级结构,而抽象工厂模式则面对多个产品等级结构
结构
- Abstract Factory
- Concrete Factory
- Abstract Product
- Product
特点
- 隔离了具体类生成,更换一个具体工厂相对容易,实现了一定程度上高内聚,低耦合
- 一个产品族的对象被设计一起工作,能保证客户端始终使用同一产品族产品
- 增加新的具体工厂和产品族很方便,无需修改系统,符合 开闭原则
- 难以扩展产生新的种类产品,由于抽象类定义了所有可能的产品集合,如此扩展需要扩展所有工厂的子类
场景
- 系统不依赖于产品类实例如何创建、组合和表达
- 系统有多余一个产品族,且每次只是用一个产品族
- 同一产品族的产品一起使用,磁约束必须在系统设计中体现
- 需要更换界面主题,包括界面中的按钮,文本框、背景色等等
Builder
复杂对象由于内部组合部件过程复杂,因此,往往外部化到一个建造者对象里,其直接返回给用户完整的产品对象,用户不关心其属性及组装方式
结构
- Builder
- Concrete Builder
- Director
- Product
特点
- 指挥者针对抽象的builder组织产品,客户只要知道具体的建造者类型,就可以通过调用指挥者获得产品
- 客户不必知道产品细节,解耦产品与产品的创建,相同创建过程创建不同产品
- 具体的建造者相对独立用户使用不同建造者构建不同产品
- 新增建造者无需修改源代码,扩展方便,符合 开闭原则
- 创建产品一般有较多共同点,组成部分相似,不适合产品差异大则不适合
- **产品内部变化复杂,**可能需要定义具体的建造者实现变化,导致系统庞大
场景
- 产品对象有复杂内部结构,通常包含多个成员属性,产品属性相互依赖要指定顺序
- 对象创建过程独立于创建该对象的类
- 游戏软件中,地图包括天空、地面、背景等组成部分,人物角色包括人体、服装、装备等组成部分
Singleton
- 某些类,只能有一个实例。全局变量可以确保对象随时被访问,但无法防止我们实例化多个对象
- 让类自身负责保存其唯一实例,如此确保没有其他实例被创建,并提供一个访问该对象的方法
- 单例模式确保一个类只有一个实例,并向系统提供这个实例
结构
特点
- 确保一个类仅有一个实例,并提供一个访问它的全局访问点
- 拥有私有构造函数,确保用户无法将其实例化
- 包含静态私有成员变量和静态共有工厂方法,工厂方法检测视力存在性,并实例化自己
- 提供唯一实例受控访问,严格控制用户访问,节约系统资源
- 也可以扩展至允许指定个数的对象实例
- 没有抽象层不好扩展,单例类责任过重
- 单例对象的生命周期以及被GC回收下次又要实例化或者对象状态丢失等问题
场景
- 只需要一个实例对象
- 只允许访问一个公共访问点
- 如果一个类有多个实例共存,则需要扩展为多例模式
Prototype
- 当我们需要复制一个对象时,创建对象并依此赋值使得代码冗余,而且很多时候许多属性不对外公开
- 原型模式委托复制过程给实际被复制的对象,该模式为要复制的类声明一个通用接口
- 一个支持复制的对象被叫做 prototype
结构
特点
- 你可以复制一个对象不耦合其具体类,帮助你摆脱重复初始化,使得生产复杂对象更方便
- 在处理复杂对象的预设配置时,除了继承之外的替代品
- 复制有循环引用的对象将会很麻烦
场景
- 当你的代码不应该依赖于具体你想拷贝的类对象
- 当你想减少子类数量,他们的不同仅仅是在初始化方式上有所不同_(通常来说,当你有一个复杂对象要初始化多次,你可以设计配置类来用于初始化复杂对象)_