设计模式总结

面向对象设计原则

单一职责原则:提高复用性。高内聚,低耦合。

开闭原则:开放拓展,关闭修改。(灵活性,稳定性,抽象化)

里氏代换原则:父类可替换为子类,反之不成立。(抽象化,代码复用,扩展性)

依赖倒转原则:针对抽象层编程。(抽象化)

接口隔离原则:多个专门的接口取代统一接口,不依赖不需要的接口。

合成复用原则:多组合聚合,少继承。(降耦合)

迪米特法则:一个软件实体尽可能少地与其他实体相互作用。只与直接朋友通信。(松耦合)

 

名称 定义 优点 缺点 适用环境 备注

简单工厂

(静态工厂)

(创建型)

根据参数的不同返回不同类的实例。

OA系统

对象的创建、使用分离。

使用配置文件,提高了系统灵活性。

客户端只需要知道产品类对应参数。

工厂类职责过重。

扩展困难。

增加了系统复杂性和理解难度。

工厂类负责创建的对象少。

不关心创建细节。

单一职责原则

降耦合

开闭原则

工厂方法

将类的实例化延迟到子类中完成,由子类决定实例化(创建)哪个类。

日志记录器

向客户隐藏哪种具体产品类被实例化。

工厂自主确定创建何种产品对象。

加入新产品符合开闭原则。

类的个数成对增加,系统复杂度提升。

增加了系统的抽象性和理解难度。

客户不知道具体产品类的类名。

抽象工厂类通过其子类指定创建哪个对象。

开闭原则

可扩展性

抽象工厂

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

电器工厂,数据库操作工厂

隔离了具体类的生成。

保证客户端始终只使用同一产品族对象。

增加新的产品族方便,符合开闭原则。

增加新的产品等级结构麻烦,违背开闭原则。

系统不依赖产品创建、组合、表达细节。

每次只使用一个产品族且所有产品一起使用。

产品等级结构稳定。

+新产品族,符合开闭。

+新产品等级结构,不符合开闭。

建造者

Builder

将复杂对象的构建与表示分离,使同样的构建可以创建不同表示。

KFC套餐,JavaMail

产品本身与产品创建过程解耦。

替换/新增具体建造者符合开闭原则。

可更精细地控制产品创建过程。

产品之间差异大则不适用。

产品内部变化复杂需更多具体建造类,导致系统过于庞大。

需要生成的产品有复杂的内部结构,属性相互依赖。

对象创建过程独立于创建对象的类。

 

原型模式

Prototype

给出一个原型对象指明所要创建的对象类型,复制这个原型对象创建更多同类型对象。

浅克隆,深克隆(序列化),邮件复制。

简化对象创建过程,提高新实例创建效率。

简化创建结构,扩展性好。

深克隆方式能保存对象状态。(撤销)

每个类需要配备一个克隆方法。

改造已有类需修改源码,改变开闭原则。

深克隆代码复杂。

创建新对象成本较大。

对象的状态变化小。

避免使用分层次工厂类。

 

单例模式

Singleton

确保一个类中只有一个实例,自行实例化并向整个系统提供这个实例。

身份证,打印池

提供了对唯一实例的受控访问。

节约系统资源,提高性能。

允许多例类。

扩展困难。

单例类职责过重。

垃圾自动回收机制丢失单例对象的状态。

只需要/允许创建一个对象。

只允许使用一个公共访问点。

 

适配器模式

(结构型)

Adaptee

将一个接口转换成客户希望的另一个接口,使接口不兼容的类可以一起工作。

机器人模仿,加密适配器

将目标类和适配器解耦。

增加了类的透明性和复用性。

灵活性和扩展性好。

类适配器:一次只适配一个适配者类。

目标抽象类只能为接口,不能为类。

对象适配器:置换适配者类的某些方法麻烦。

系统需要使用一些现有的类,而这些类的接口不符合系统需要。

创建一个可以重复使用的类。

 

桥接模式

Implementor

抽象与实现部分分离,使他们可以独立地变化。

大中小彩色毛笔,跨平台视频播放器

分离抽象接口及其实现部分。

取代多层继承,减少子类个数。

提高系统的可扩展性。

增加系统的理解与设计难度。

难以正确识别系统中两个独立变化的维度。

增加抽象化和具体化间的灵活性。

抽象、实现部分独立扩展互不影响。

不希望使用继承。

 

组合模式

Leaf

组合多个对象形成树形结构以表示整体-部分的结构层次,对单个对象和组合对象的使用具有一致性。

水果盘,文件浏览

定义分层次复杂对象,忽略层次差异。

增加新容量构件和叶子构件方便。

实现树形结构面向对象。

抽象复杂,难度大。

增加新构件时很难对容器中的构件类型进行限制。

希望客户一致对待整体,部分层次结构。

面向对象开发系统中处理树形结构。

系统中可分离出叶子和容器对象。

 

装饰模式

Decorator

动态地给一个对象增加一些额外职责。

变形金刚变飞机、机器人,多重加密系统

比继承灵活,不会急剧增加类的个数。

动态方式扩展对象功能。

可对一个对象多次装饰。

加新的构件类和装饰类符合开闭原则。

一定程度下影响对象性能。

比继承更易出错,难排错。

动态透明地给单个对象添加职责。

不能采用继承方式扩展系统。

 

外观模式

Facade

为复杂子系统提供一个统一入口。

电源总开关,文件加密外观类,

减少了客户端所需处理的对象数目。

实现了子系统与客户端间的松耦合。

子系统修改对其他子系统,外观无影响。

不能很好地限制客户端直接使用子系统类。

增加新子系统需修改外观类,违背开闭原则。

为复杂子系统提供简单入口。

客户端与多个子系统存在依赖性。

层次性结构通过外观类建立联系。

迪米特法则

降耦合

代理模式

Proxy

给对象提供一个代理,并由代理对象控制原对象的引用。

论坛权限控制,图片预览

协调调用者、被调用者,降耦合。

增加/更换代理类无须修改代码,符合开闭原则。

(保护代理)可能造成请求处理缓慢。

(远程代理)实现过程复杂。

远程代理,虚拟代理(预览),缓冲代理(共享访问),保护代理(权限),智能引用代理  

命令模式(对象型行为模式)

Invoker

将一个请求封装为一个对象,使请求调用者和接收者解耦。

电视遥控器(开关,exchange),功能键

降低系统耦合度。

新命令易加入系统,符合开闭原则。

命令队列,宏命令,请求撤销,恢复。

可能会导致某些系统有过多具体命令类。

将请求调用者和接收者解耦。

不同时间指定请求,请求排队,执行命令撤销,恢复。

 

迭代器模式

Iterator

提供一种方法访问聚合对象,而不暴露对象的内部表示。

遥控器换台

同一聚合对象可定义多种遍历方式。

简化了聚合类。

增加聚合类、迭代器方便,符合开闭原则。

增加新聚合类需要新迭代器类,复杂性提升。

设计难度大,很难全面考虑。

访问聚合对象内容而不暴露内部。

为一个聚合类提供多种遍历方式。

为遍历不同聚合结构提供统一接口。

单一职责原则

观察者模式

Observer

定义了对象间的一种一对多依赖关系,使每当一个对象状态改变时,其依赖对象得到通知并被自动更新。

猫狗鼠,MVC,自定义登录控件

可实现表示层与数据逻辑层分离。

支持广播通信,一对多。

在观察目标和观察者间建立了一个抽象耦合。

增加具体观察者和观察目标符合开闭原则。

通知所有观察者会花费很多时间。

如有循环依赖可能使系统崩溃。

观察者不知道目标对象是怎么发生变化的。

抽象模型一方面依赖于另一方面。

一个对象改变会导致别的对象改变。

需要在系统中创建一个触发链。

 

状态模式

State

允许一个对象在其内部改变时改变它的行为。

论坛用户等级,人开心时笑伤心时哭,银行账户余额为正则绿、欠款则红

封装状态转换规则,集中管理代码。

注入不同状态可使环境对象行为不同。

允许状态转换逻辑与状态对象合成一体。

多环境对象共享一个状态对象,可以减少类的个数。

增加类和对象的个数,增大开销。

使用不当代码会导致混乱,增加难度。

新增/修改状态类不符合开闭原则。

状态改变导致对象行为变化。

代码有大量与对象状态有关的条件语句。

 

策略模式

Strategy

定义一系列算法,并将每个算法封装在一个类中,并让他们可以互相替换。让算法独立于使用它的客户而变化。

旅游出行策略,排序策略

支持开闭原则,可管理相关算法族。

可替换继承,提高算法复用。

避免多重条件语句。

客户端必须知道所有策略类并进行选择。

可能造成系统产生很多具体策略类。

无法同时使用多个策略类。

一个系统需动态地在多种算法中选择一个。

避免使用难以维护的多重条件选择。

不希望客户知道与算法相关的数据结构。

算法保密性

安全性

 

 
 
 
 
 
posted @ 2022-05-31 23:01  临易  阅读(384)  评论(0编辑  收藏  举报