创建型模式
创建型模式提供了创建对象的机制, 能够提升已有代码的灵活性和可复用性。
-
工厂方法
- 在父类中提供一个创建对象的接口以允许子类决定实例化对象的类型
-
抽象工厂
- 让你能创建一系列相关的对象,而无需指定其具体类
-
生成器
- 使你能够分步骤创建复杂对象。允许你使用相同的创建代码生成不同类型和形式的对象。
-
原型
- 让你能够复制已有对象,而又无需使代码依赖它们所属的类。
-
单例
- 让你能够保证一个类只有一个实例,并提供一个访问该实例的全局节点。
比较
名称 | 工厂方法模式 | 抽象工厂模式 | 生成器模式 | 原型模式 | 单例模式 |
---|---|---|---|---|---|
英文名称 | 虚拟构造函数、Virtual Constructor、Factory Method | 亦称: Abstract Factory | 亦称: 建造者模式、Builder | 亦称: 克隆、Clone、Prototype | Singleton |
意图 | 工厂方法模式是一种创建型设计模式, 其在父类中提供一个创建对象的方法, 允许子类决定实例化对象的类型。 | 抽象工厂模式是一种创建型设计模式, 它能创建一系列相关的对象, 而无需指定其具体类 | 生成器模式是一种创建型设计模式, 使你能够分步骤创建复杂对象。 该模式允许你使用相同的创建代码生成不同类型和形式的对象。 | 原型模式是一种创建型设计模式, 使你能够复制已有对象, 而又无需使代码依赖它们所属的类。 | 单例模式是一种创建型设计模式, 让你能够保证一个类只有一个实例, 并提供一个访问该实例的全局节点 |
模式优点 | 你可以避免创建者和具体产品之间的紧密耦合。 单一职责原则。 你可以将产品创建代码放在程序的单一位置, 从而使得代码更容易维护。 开闭原则。 无需更改现有客户端代码, 你就可以在程序中引入新的产品类型 | 你可以确保同一工厂生成的产品相互匹配。 你可以避免客户端和具体产品代码的耦合。 单一职责原则。 你可以将产品生成代码抽取到同一位置, 使得代码易于维护。 开闭原则。 向应用程序中引入新产品变体时, 你无需修改客户端代码。 | 你可以分步创建对象, 暂缓创建步骤或递归运行创建步骤。 生成不同形式的产品时, 你可以复用相同的制造代码。 单一职责原则。 你可以将复杂构造代码从产品的业务逻辑中分离出来。 | 你可以克隆对象, 而无需与它们所属的具体类相耦合。 你可以克隆预生成原型, 避免反复运行初始化代码。 你可以更方便地生成复杂对象。 你可以用继承以外的方式来处理复杂对象的不同配置。 | 你可以保证一个类只有一个实例。 你获得了一个指向该实例的全局访问节点。 仅在首次请求单例对象时对其进行初始化。 |
模式缺点 | 应用工厂方法模式需要引入许多新的子类, 代码可能会因此变得更复杂。 最好的情况是将该模式引入创建者类的现有层次结构中。 | 由于采用该模式需要向应用中引入众多接口和类, 代码可能会比之前更加复杂。 | 由于该模式需要新增多个类, 因此代码整体复杂程度会有所增加。 | 克隆包含循环引用的复杂对象可能会非常麻烦。 | 违反了_单一职责原则_。 该模式同时解决了两个问题。 单例模式可能掩盖不良设计, 比如程序各组件之间相互了解过多等。 该模式在多线程环境下需要进行特殊处理, 避免多个线程多次创建单例对象。 单例的客户端代码单元测试可能会比较困难, 因为许多测试框架以基于继承的方式创建模拟对象。 由于单例类的构造函数是私有的, 而且绝大部分语言无法重写静态方法, 所以你需要想出仔细考虑模拟单例的方法。 要么干脆不编写测试代码, 或者不使用单例模式。 |
说明 | 单个系列产品 | 多系列产品 | 分步骤创建复杂对象 | 复制已有对象 | 一个类只有一个实例 |
Java 常用设计模式 | 在父类中提供一个创建对象的接口以允许子类决定实例化对象的类型。 | 让你能创建一系列相关的对象, 而无需指定其具体类。 | 使你能够分步骤创建复杂对象。 该模式允许你使用相同的创建代码生成不同类型和形式的对象。 | 让你能够复制已有对象, 而又无需使代码依赖它们所属的类。 | 让你能够保证一个类只有一个实例, 并提供一个访问该实例的全局节点。 |