Table of Contents
理解三个核心创建模式
软件设计模式是经过战斗测试的解决反复出现的设计问题的蓝图。 最常见的使用模式包括:关于物体如何被即时化的创造模式 — — 银河、工厂和原型。 选择正确的一种直接冲击代码的可维护性、性能和可扩展性。 这个扩展的指南深入到每一种模式中,探索现实世界的情景,并提供可操作的标准帮助您做出知情的决定。
Singleton 模式: 统治全部的单一实例
Singleton模式确保一个类有一个完全的实例,并提供了一个全局访问点。它是最简单的模式之一,但经常被滥用。核心思想是控制即时进程,这样无论请求的类有多少次,都返回同一个对象。
单子顿如何工作
通常情况下,Singleton类具有一个私有构造器和返回实例的静态方法。第一个调用创建对象;随后调用重复使用同一实例。在多线程环境中,需要同步来防止可能产生多个实例的种族条件。
public class DatabaseConnectionPool {
private static DatabaseConnectionPool instance;
private DatabaseConnectionPool() { /* initialization */ }
public static synchronized DatabaseConnectionPool getInstance() {
if (instance == null) {
instance = new DatabaseConnectionPool();
}
return instance;
}
}
当Singleton闪耀时
- 管理共享资源:连接池,日志服务,或配置管理器从单一的点协调中受益.
- 全局状态: 当一个全应用缓存或注册需要一致的存取时.
- 硬件或OS级资源:[文件系统,打印机拼接器,或窗口管理器通常只允许一个实例.
避免的常见陷阱
- 过度使用:[ 利用Singleton为一切带来隐藏的依赖性,使单位测试变得硬化,因为你无法轻易地用一个模拟器取代实例.
- Thread-security over: 经典同步方法可以成为瓶颈. 诸如急速初始化或双检查锁(带有挥发性)等替代方法可以减少争议.
- 紧接: 由于全局接入点是硬编码的,客户端会与混凝土Singleton类结合,违反了依赖性反转原则.
尽管有这些缺点,但当您真正需要一个单一的、全球可访问的对象时,Singleton仍然有用。关于更深入的理解,请参见 重构古鲁的Singleton指南。
工厂模式: 授权对象创建
Factory 模式封装对象即时逻辑,允许子类决定哪个类别进行即时处理。它主要有两种口味: Factory Method (一种返回新对象的单一方法)和[Abstract Factory [ (一种由相关工厂方法组成的家族) 两种都从混凝土类中解开客户代码,促进松散的耦合和更容易的扩展性.
工厂方法详细
定义创建对象的界面, 但让子类更改将要创建的对象类型。 例如, 对话框类可能有一个方法 [ [[FLT: 1]] 。 子类如 WindowsDialog 和 LinuxDialog 覆盖此方法以返回平台特定按钮 。
abstract class Dialog {
abstract Button createButton();
public void render() {
Button okButton = createButton();
okButton.onClick();
}
}
class WindowsDialog extends Dialog {
Button createButton() { return new WindowsButton(); }
}
这样的模式在下列情况下是理想的:
- 类不能预见它必须创建的对象的类别 。
- 您想要将对象创建逻辑定位在一个地方 。
- 系统需要独立于其对象的构造方式.
抽象工厂:生产相关物品的家庭
抽象工厂提供了创建关联或依赖对象家族的接口,而未指定其混凝土类. 想想GUI工具包,它必须产生一个按键,复选框,以及滚动条,这些按键在指定主题(如材料,Cupertino)下看起来一致. 客户端使用抽象工厂界面来获取产品,混凝土工厂(MatrialFactory,CupertinoFactory)生成正确的变体.
选择此模式时:
- 该系统必须配置成多个产品家族中的一个。
- 您想要强制要求产品之间保持一致性 。
- 增加新产品家庭需要对现有代码进行最小的修改.
在工厂和其他模式之间作出决断
当对象创建复杂或需要运行时交换执行时,工厂是您要进入的。它比Singleton更灵活,因为它不限制实例的数量,而只是集中创建。与原型不同的是,工厂从零开始创建新的实例,而不是复制现有的实例。对于两种变体,请访问 重新确定古鲁工厂方法的页面[ 和 Abstract Fact Factory页面。
原型模式: 克隆取代构造
原型模式通过复制一个已有对象——原型来创建新对象。 当即时化费用昂贵(例如,重数据库查询、复杂的几何计算)或对象配置耗时,它特别有价值。您不从零开始构建,而是克隆一个预配置实例,并按需要对其进行调整。
克隆机械师:浅色对深层复制
大多数编程语言都提供了内置克隆方法(),在Java,在Python,或分布在JavaScript中。但是,必须仔细注意复制是浅(共享可变对象的参考文献)还是深(完全独立). 深复制递录复制克隆所引用的所有对象。在执行Prototype时,必须决定复制的级别与您的使用大小写相符.
class MazePrototype {
public MazePrototype clone() throws CloneNotSupportedException {
return (MazePrototype) super.clone(); // shallow copy
}
}
原型的理想情景
- 核心对象创建: 例如,从文件中装入一个大配置或者生成一个复杂的几何网格.
- Dynamic runtime对象: 当系统必须生成在运行时间确定类型的新对象(例如,在从预定义模板中产化的游戏中的敌人类型)时.
- 减少子类爆炸:[ 与其为微小的变异创建许多子类,不如克隆一个原型,调整几个属性.
原型登记和缓存
您可以通过实施一个注册系统—— 由密钥索引的预建原型的中央存储系统, 进一步采取原型。 客户请求按密钥进行原型, 复制并定制。 在某些情况下, 原型与注册系统相结合, 可作为工厂或Singleton 的轻量级替代。 详细走过, 请参见 [ [FLT: 0]] 重构 Gru 的原型指南 。
边边比较:单子、工厂、原型
为了帮助您选择,下表突出关键差异:
| Pattern | Instance Count | Creation Mechanism | Best For |
|---|---|---|---|
| Singleton | Exactly one | Self-managed global access | Shared resources, global state |
| Factory | Multiple instances (or families) | Centralized creation logic | Decoupling client from concrete classes, complex creation |
| Prototype | Multiple instances cloned from a template | Cloning (shallow/deep copy) | Expensive instantiation, runtime object generation |
当模式重叠或组合时
- 辛莱顿+工厂: 工厂本身可以是单子(例如每个平台一个抽象工厂),这把全球接入与集中创建结合起来.
- 原型+工厂: 原型注册可以充当工厂——你克隆原型而不是叫构造者,这在产卵实体时的游戏开发中特别有用.
- Prototype + Singleton: 一个原型物体可能是单子,意思是每个类型只存在一个原型实例,尽管克隆人不是单子.
实际决定框架
当遇到设计问题,需要建立创建模式时,请按以下顺序问这些问题: 1.
- ” 我在整个申请过程中需要一次吗? 如果有,请考虑Singleton。 但要确保真正需要全球共享状态,而且检验能力不会受到影响。
- 对象创建是否复杂或可能改变? 如果有,则使用工厂方法或摘要工厂。这在您预计以后会添加新的对象类型时特别有用。
- 对象创建是性能瓶颈,还是我需要很多只稍有不同的例子? 如果是,原型可以通过克隆一个模板来节省时间和内存.
- 多个模式能否达到同样的目的? 权衡权衡。例如,如果目标共享不可变数据,一个飞行量度模式可能会减少内存而不是原型。
工程软件中的真实世界实例
工程应用经常混合这些模式。一个CAD系统可能会使用Singleton来为用户首选项管理器,Factory来创建各种几何形状(圆形,多边形,丝状),以及克隆一个复杂组装然后修改的原型。一个模拟引擎可以使用Factor来创建不同的解析对象,用于复制粒子系统配置的原型,以及用于记录所有模拟步骤的日志服务。
结论:不要让模式化您的设计
单子、工厂和原型是基本创造模式,但并不是银子弹。 最好的选择来自理解你的系统限制:比如控制的必要性、物体创造的复杂性和新事件的成本。 总是倾向于清晰和可检验性,而不是模式纯度。 当怀疑时,从工厂开始 — — 它提供最干净的解耦,如果情况需要,它可以被原型或单子顿取代或扩充。
通过掌握这三种模式,您可以装备一个多功能工具包,用于构建强健灵活的工程软件. 欲进一步阅读,请探索关于软件设计模式的维基百科文章和 重构古鲁对创造模式的概述.