设计模式整理
自己也学习了很久的设计模式了,今天就稍微进行下整理,方便自己以后回看。
工厂模式
工厂模式有简单工厂、工厂模式、抽象工厂等等。具体实现是同一种规则:在父类中提供一个创建对象的方法, 允许子类决定实例化对象的类型,将实例化对象的操作延迟到工厂子类。
实例
日志记录器。
支持多种日志记录方式,如数据日志、时间日志、事件日志等。且可以根据客户要求动态地选择日志记录的方式。
优点
- 可以避免创建者和具体产品之间的紧密耦合。
- 单一职责原则。可以将产品创建代码放在程序的单一位置,从而使得代码更容易维护。
- 开闭原则。无需更改现有客户端代码,你就可以在程序中引入新的产品类型。
缺点
- 难于理解,增加系统复杂度,增加开销。
策略模式
允许定义一系列算法,并将每种算法分别放入独立的类中,以使算法的对象能够相互替换。
抽象算法类定义算法方法,子类实现。工具类维护算法子类,通过实例化不同算法子类,调用算法。客户端使用工具类。
优点
- 你可以在运行时切换对象内的算法。
- 你可以将算法的实现和使用算法的代码隔离开来。
- 你可以使用组合来代替继承。
- 开闭原则。你无需对上下文进行修改就能够引入新的策略。
缺点
- 增加系统复杂度,增加开销。
- 客户端必须知晓策略间的不同——它需要选择合适的策略。
装饰模式
装饰模式是一种结构型设计模式, 允许你通过将对象放入包含行为的特殊封装对象中来为原对象绑定新的行为,注入。与适配器模式使用场景不同。
被装饰对象类和装饰类继承同一个抽象类,override相同方法,接口保持一致。
装饰类中调用被装饰对象该方法,再添加其他行为。类似子类继承基类,同时添加其他方法。不新增加子类。
客户端调用具体装饰类。具体装饰类实现抽象装饰类,抽象装饰类继承元接口,同时依赖注入一个元接口实例对象,对该对象进行装饰。
优点
- 你无需创建新子类即可扩展对象的行为。
- 你可以在运行时添加或删除对象的功能。
- 你可以用多个装饰封装对象来组合几种行为。
- 单一职责原则。你可以将实现了许多不同行为的一个大类拆分为多个较小的类。
缺点
- 使用装饰模式会产生很多类,增加系统的复杂度。
- 多层装饰比较复杂,排错需一层层检查。
代理模式
代理模式是一种结构型设计模式,让你能够提供对象的替代品或其占位符。代理控制着对于原对象的访问,并允许在将请求提交给对象前后进行一些处理。
优点
- 你可以在客户端毫无察觉的情况下控制服务对象。
- 如果客户端对服务对象的生命周期没有特殊要求,你可以对生命周期进行管理。
- 即使服务对象还未准备好或不存在,代理也可以正常工作。
- 开闭原则。你可以在不对服务或客户端做出修改的情况下创建新代理。
用例
通过代理来实现延迟加载,当一个对象加载消耗资源过大时,可通过代理将其加载延迟至使用时再加载。
- 远程代理
- 虚拟代理
- 缓冲
原型模式
原型模式是一种创建型设计模式,使你能够复制已有对象,而又无需使代码依赖它们所属的类。
原型类提供clone函数,客户端复制使用新对象调用该函数。
优点
- 你可以克隆对象,而无需与它们所属的具体类相耦合。
- 你可以克隆预生成原型,避免反复运行初始化代码。
- 你可以更方便地生成复杂对象。
- 你可以用继承以外的方式来处理复杂对象的不同配置。
模板方法
模板方法模式是一种行为设计模式,它在超类中定义了一个算法的框架,允许子类在不修改结构的情况下重写算法的特定步骤。
基于继承,父类定义如何使用抽象方法,子类各自实现抽象方法,不改变父类中使用抽象方法的顺序。
外观模式
外观模式是一种结构型设计模式,能为程序库、框架、子系统或其他复杂类提供一个简单的接口。
将一整块内容用一个类或接口包裹住,在其中实现提供调用被包裹内容的各种方法。
优点
- 可以将主系统与子系统,层与层之间解耦
- 提高了灵活性与安全性
缺点
- 增加或修改子系统需要额外修改外观类
建造者模式
生成器模式是一种创建型设计模式,使你能够分步骤创建复杂对象。该模式允许你使用相同的创建代码生成不同类型和形式的对象。
将建造的过程剥离到建造者类中,建造者类返回一个完整的对象,用户无需知道建造过程。
分为客户端,指挥类和建造类。建造子类分别不同地实现抽象建造类的方法。指挥类调用抽象建造类对象实现建造。客户端将不同建造子类对象给指挥类。
实例
各种套餐组合。
优点
- 你可以分步创建对象,暂缓创建步骤或递归运行创建步骤。
- 生成不同形式的产品时,你可以复用相同的制造代码。
- 单一职责原则。你可以将复杂构造代码从产品的业务逻辑中分离出来。
缺点
- 使用有限制,差别过大的产品不适合使用同一建造者。
- 如果产品内部很复杂,建造者类会很复杂。
观察者模式
观察者模式是一种行为设计模式, 允许你定义一种订阅机制, 可在对象事件发生时通知多个 “观察” 该对象的其他对象。
订阅机制,委托。
抽象工厂
工厂和产品都抽象化,更抽象更复杂开销更大。
抽象工厂模式与工厂方法模式最大的区别在于,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式则需要面对多个产品等级结构。
一个工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建 。
当一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象时,抽象工厂模式比工厂方法模式更为简单、有效率。
状态模式
状态模式是一种行为设计模式,让你能在一个对象的内部状态变化时改变其行为,使其看上去就像改变了自身所属的类一样。
如果对象根据自身的状态不同,进行不同操作,且状态切换频繁时,可以使用状态模式。
状态抽象类,子类继承实现不同行为。客户端通过传入判断参数,或子类的行为中自行切换类型,来实现状态改变
优点
- 通过消除臃肿的状态机条件语句简化上下文代码。
适配器模式
将一个类的接口转换成另外一个接口,使接口不兼容的对象能够相互合作。
优点
- 灵活性和扩展性都非常好。
- 将目标类与适配类解耦,增加了类的透明性和复用性。
缺点
- 适配器类的更换比较复杂。
- 过多地使用适配器,会让系统非常零乱,不易整体进行把握。如果不是很有必要,可以不使用适配器,而是直接对系统进行重构
备忘录模式
备忘录模式是一种行为设计模式, 允许在不暴露对象实现细节的情况下保存和恢复对象之前的状态。
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
组合模式(整体/部分模式)
组合模式是一种结构型设计模式,你可以使用它将对象组合成树状结构,并且能像使用独立对象一样使用它们。
树状结构。抽象组合类,定义add和remove方法和其他方法。leaf子类,不能使用add和remove方法,没有下级对象。compsite子类,有一个根节点,可以add或remove叶节点或其他枝干节点。
使用场景
- 按树状结构来组织和处理对象
- 使用同一方法处理单个对象和一组对象
优点
- 你可以利用多态和递归机制更方便地使用复杂树结构。
- 开闭原则。无需更改现有代码,你就可以在应用中添加新元素,使其成为对象树的一部分。
缺点
- 在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。
- 设计
迭代器模式
循环迭代
单例模式
使用很频繁
桥接模式
桥接模式是一种结构型设计模式,可将一个大类或一系列紧密相关的类拆分为抽象和实现两个独立的层次结构,从而能在开发时分别使用。
将抽象部分与它的实现部分分离,使它们都可以独立变化。
尽量使用合成/聚合,尽量不要使用类继承。
桥接模式中的所谓脱耦,就是指在一个软件系统的抽象化和实现化之间使用关联关系(组合或者聚合关系)而不是继承关系,从而使两者可以相对独立地变化,这就是桥接模式的用意。
简单解析
抽象类或接口,通过依赖注入另一个抽象类或接口的实例,实现两种变化的加法关系实现。
如果使用多继承,两种变化是m*n的类实现。使用聚合(依赖注入),两种变化是m+n的类实现。即将m中变化实例注入到n个变化实例中。这个操作称为桥接。
使用场景
- 如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。
- 对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。
- 一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。
优点
- 抽象和实现的分离。
- 优秀的扩展能力。
- 实现细节对客户透明。
缺点
使用桥接模式会增加系统的复杂度,更难于让人理解。
命令模式
命令模式是一种行为设计模式,它可将请求转换为一个包含与请求相关的所有信息的独立对象。该转换让你能根据不同的请求将方法参数化、延迟请求执行或将其放入队列中,且能实现可撤销操作。
command抽象类,可以只有抽象操作。
command命令子类,实例化各种操作,可以在命令子类中使用receiver类对象来处理命令。receiver接收者类对象,可以和invoker命令调用类毫无关系。
invoker命令调用类,持有一个或多个command类对象,有命令类对象add方法和invoke调用命令类对象的方法。
客户端实例化各种命令子类对象和命令调用类对象,如果有接收者类对象,和命令子类对象一起使用。给命令调用类对象添加各种命令,并调用触发方法发送命令。
优点
- 单一职责原则。你可以解耦触发和执行操作的类。
- 开闭原则。你可以在不修改已有客户端代码的情况下在程序中创建新的命令。
- 你可以实现撤销和恢复功能。
- 你可以实现操作的延迟执行。
- 你可以将一组简单命令组合成一个复杂命令。
责任链模式
责任链模式是一种行为设计模式,允许你将请求沿着处理者链进行发送。收到请求后,每个处理者均可对请求进行处理,或将其传递给链上的下个处理者。
Handler抽象类,定义了一个保存对于下个处理者引用的成员变量。Handler子类负责决定是否处理,或者沿着链传递,有具体处理方法。
客户端生成责任链,并可以向任意对象发送请求。客户端组装责任链,为每个链节点设置各自的下一个节点。
优点
- 你可以控制请求处理的顺序。
- 单一职责原则。你可对发起操作和执行操作的类进行解耦。
- 开闭原则。你可以在不更改现有代码的情况下在程序中新增处理者。
缺点
- 请求不一定会被接收
用例
- wpf中的按钮响应等事件。
- 一系列的登陆信息/数据验证等。
- 按顺序处理一系列的请求,且请求类型和顺序未知时可以使用
中介者模式
中介者模式是一种行为设计模式,能让你减少对象之间混乱无序的依赖关系。该模式会限制对象之间的直接交互,迫使它们通过一个中介者对象进行合作。
类似MVC里的C,controller。
将大量的网状结构对象,通过中介者对象,梳理成星型结构。中介者可能会变得复杂难以维护
享元模式
享元模式是一种结构型设计模式,它摒弃了在每个对象中保存所有数据的方式,通过共享多个对象所共有的相同状态,让你能在有限的内存容量中载入更多对象。
FlyweightFactory享元工厂,利用键值对相似技术用来创建并管理享元对象。用户请求时没有则创建,已有则返回。Flyweigth享元抽象类,子类分为可共享和不可共享。
客户端从享元工厂获取享元对象,共享对象没有工厂会创建,已有则返回。类似各种池。
优点
- 如果程序中有很多相似对象,那么你将可以节省大量内存。
缺点
- 提高了系统复杂度,容易造成系统混乱

浙公网安备 33010602011771号