10设计模式
2021-02-05 16:20:47 1 举报
AI智能生成
系统架构师考试时学习整理的
作者其他创作
大纲/内容
设计模式概述
设计模式的概念
(1)学习这些模式是一个方面,另一方面更要了解模式中的思想
(2)设计模式虽然可以使设计变得更精妙,但滥用设计模式会适得其反
设计模式的组成
在描述一个设计模式时,至少需要包含四个方面:模式名称(Pattern name)、
问题(Problem)、解决方案(Solution)、效果(Consequence)。这四个方面就是设计模式的四要素
GoF 设计模式
(1)Factory Method 模式。Factory Method 模式提供了一种延迟创建类的方法,使用这个方法可以在运行期由子类决定创建哪一个类的实例
(2)Abstract Factory 模式。Abstract Factory 又称为抽象工厂模式,该模式主要为解决复杂系统中对象创建的问题。抽象工厂模式提供了一个一致的对象创建接口来创建一系列具有相似基类或相似接口的对象
(3)Builder 模式。Builder 模式与 Abstract Factory 模式非常类似,但 Builder 模式是逐步地构造出一个复杂对象,并在最后返回对象的实例。Builder 模式可以把复杂对象的创建与表示分离,使得同样的创建过程可以创建不同的表示
(4)Prototype 模式。Prototype 模式可以根据原型实例制定创建的对象的种类,并通过深复制这个原型来创建新的对象。Prototype 模式有着同 Abstract Factory 模式和 Builder模式相同的效果,不过当需要实例化的类是在运行期才被指定的而且要避免创建一个与产品曾是平行的工厂类层次时,可以使用 Prototype 模式。使用 Prototype 模式可以在运行时增加或减少原型,比 Abstract Factory 和 Builder 模式更加灵活
(5)Singleton 模式。Singleton 模式也是一种很有代表性的模式。使用 Singleton 模式可以保证一个类仅有一个实例,从而可以提供一个单一的全局访问点
(6)Adapter 模式。Adapter 模式可以解决系统间接口不相容的问题。通过 Adapter 可以把类的接口转化为客户程序所希望的接口,从而提高复用性
(7)Bridge 模式。Bridge 模式把类的抽象部分同实现部分相分离,这样类的抽象和实现都可以独立地变化
(8)Composite 模式。Composite 模式提供了一种以树形结构组合对象的方法,使用Composite 可以使单个对象和组合后的对象具有一致性以提高软件的复用性
(9)Decorator 模式。Decorator 模式可以动态地为对象的某一个方法增加更多的功能。在很多时候,使用 Decorator 模式可以不必继承出新的子类从而维护简洁的类继承结构
(10)Facade 模式。Facade 模式为一组类提供了一致的访问接口。使用 Facade 可以封装内部具有不同接口的类,使其对外提供统一的访问方式。Facade 模式在 J2EE 系统开发中发展为 Session Facade 模式
(11)Flyweight 模式。Flyweight 模式可以共享大量的细粒度对象,从而节省创建对象所需要分配的空间,不过在时间上的开销会变大
(12)Proxy 模式。顾名思义,Proxy 模式为对象提供了一种访问代理,通过对象 Proxy可以控制客户程序的访问。例如:访问权限的控制、访问地址的控制、访问方式的控制等,甚至可以通过 Proxy 将开销较大的访问化整为零,提高访问效率
(13)Interpreter 模式。定义了一个解释器,来解释遵循给定语言和文法的句子
(14)Template Method 模式。定义一个操作的模板,其中的一些步骤会在子类中实现,以适应不同的情况
(15)Chain of Responsibility 模式。Chain of Responsibility 模式把可以响应请求的对象组织成一条链,并在这条对象链上传递请求,从而保证多个对象都有机会处理请求而且可以避免请求方和相应方的耦合
(16)Command 模式。将请求封装为对象,从而增强请求的能力,如参数化、排队、记录日志等
(17)Iterator 模式。Iterator 模式提供了顺序访问一个对象集合中的各元素的方法,使用 Iterator 可以避免暴露集合中对象的耦合关系
(18)Mediator 模式。Mediator 模式可以减少系统中对象间的耦合性。Mediator 模式使用中介对象封装其他的对象,从而使这些被封装的对象间的关系就成了松散耦合
(19)Memento 模式。Memento 模式提供了一种捕获对象状态的方法,且不会破坏对象的封装。并且可以在对象外部保存对象的状态,并在需要的时候恢复对象状态
(20)Observer 模式。Observer 模式提供了将对象的状态广播到一组观察者的方式,从而可以让每个观察者随时可以得到对象更新的通知
(21)State 模式。State 模式允许一个对象在其内部状态改变的时候改变它的行为
(22)Strategy 模式。使用 Strategy 模式可以让对象中算法的变化独立于客户
(23)Visitor 模式。表示对某对象结构中各元素的操作,使用 Visitor 模式可以在不改变各元素类的前提下定义作用于这些元素的新操作
其他设计模式
(1)Intercepting Filter 模式:通过截取客户请求,并将请求发送到 Filter 链中,一步一步地进行预处理,直到这些处理结束,请求才会被转发到真正响应客户请求的 Servlet 中
(2)Session Facade 模式
设计模式与软件架构
设计模式则更侧重于类与类、对象与对象之间的关系
设计模式分类
设计模式是面向问题的,即每一种设计模式都是为了解决一种特定类型的问题。因此,根据设计模式要解决的问题将设计模式分为三类,分别为创建型、结构型和行为型
表现层模式、业务层模式和综合层模式
设计模式及实现
Abstract Factory 模式
1.模式名称
Abstract Factory,也经常称之为抽象工厂模式
2.意图解决的问题
(1)object new ClassName 是最常见的创建对象方法,但这种方法造成类名的硬编码,需要根据不同的运行环境动态加载相同接口但实现不同的类实例,这样的创建方法就需要配合上复杂的判断,实例化为不同的对象
(2)为了适用于不同的运行环境,经常使用抽象类定义接口,并在不同的运行环境中实现这个抽象类的子类。普通的创建方式必然造成代码同运行环境的强绑定,软件产品无法移植到其他的运行环境
3.模式描述
Abstract Factory 类将接受 Client 的“订单”——Client 发送过来的消息,使用不同的“车间”——不同的 Concrete Factory,根据已有的“产品模型”——Abstract Product,生产出特定的“产品”——Product。不同的车间生产出不同的产品供客户使用,车间与产品的关系是一一对应的。由于所有的产品都遵循产品模型——AbstractProduct,具有相同的接口,所以这些产品都可以直接交付客户使用
4.效果
应用 Abstract Factory 模式可以实现对象可配置的、动态的创建。灵活运用 AbstractFactory 模式可以提高软件产品的移植性,尤其是当软件产品运行于多个平台,或有不同的功能配置版本时,抽象工厂模式可以减轻移植和发布时的压力,提高软件的复用性
5.相关讨论
Product Factory 既可以看作抽象工厂 Abstract Factory,也可以看作具体的
工厂(车间) Concrete Factory 。其中提供了一个获得产品的方法: getProduct
(productName:String),该方法将根据产品的名称创建特定的产品,并返回。所有的产品都实现了 Product 接口,可以在客户程序中加以使用。同抽象工厂模式一样,工厂中获得对象的方法(getProduct())与实际的产品线数量是一致的,如果要增加新的产品线——例如定义新的产品接口 ProductX,需要增加相应的 getProduct()方法。由于这种方式把 AbstractFactory 和 Concrete Factory 合并为一个 Product Factory,所以增加新的实现 Product 接口的 Productn 不需要修改任何代码
优点
① 可配置的对象创建方法可以提高系统的移植性和复用性
② 充分利用面向对象多态的特性可以避免对象创建过程的硬编码
Singleton 模式
1.模式名称
Singleton,也常称之为单件模式或单根模式
2.意图解决的问题
在软件开发中,开发人员希望一些服务类有且仅有一个实例供其他程序使用。例如,短消息服务程序或打印机服务程序,甚至对于系统配置环境的控制,为了避免并发访问造成的不一致,也希望仅为其他程序提供一个实例
3.模式描述
在 Singleton 中,通过将 Singleton 类的构造函数设为 protected 型(或 private)来防止外部对其直接初始化。需要访问 Singleton 的程序必须通过 getInstance()方法来获得一个 Singleton。在getInstance() 中仅创建一次 uniqueInstance 就可以保证系统中的唯一实例
4.效果
使用 Singleton 模式可以保证系统中有且仅有一个实例,这对于很多服务类或者环境配置类来说非常重要
5.相关讨论
需要注意
(1)Singleton 仅能保证在单一系统内的单一实例。如果使用分布式构件,如运行在多个 JVM 下的 EJB,上面的实现方法是不能保持整个系统中的单一实例的
(2)Singleton 模式仅适用于系统中至多有一个实例的情况,应避免滥用。很多过度设计的 Singleton 同使用了静态方法的工具类一样,没有任何必要,反而可能降低效率
(3)从 Singleton 的实现就可以看出,Singleton 不支持继承
Decorator 模式
1.模式名称
Decorator 模式,又称装饰模式或油漆工模式
2.意图解决的问题
在开发时,经常会发现为类预先设计的功能并不够强大,需要增强或扩展类的功能。解决这个问题的最简单的办法是继承出一个新的类,并扩展相应的方法。但是这样做会产生大量的子类,让系统中类的层次结构变得复杂且混乱。Decorator 模式通过在原有类的基础上包装一层来解决功能扩展的问题
3.模式描述
DecoratorComponent 是 ConcreteComponent 的装饰类,它们继承自同一个抽象类Component,拥有相同的接口。对于 ConcreteComponent 的装饰可能不止一种,因此又继承出 ConcreteDecorator1 和 ConcreteDecorator2 来作为具体的装饰类。这个结构在类层次上是很清晰的,比静态继承更具有灵活性
4.效果
Decorator 模式可以动态地扩展类的功能,同时又避免继承出大量的子类,比继承的方法更灵活。由于 Decorator 提供了动态的扩展方法,因此可以随时根据具体需求产生新的装饰类,从而可以在一定程度上避免层次较高类的复杂性。但是大量使用 Decorator 模式会造成系统中出现很多接口类似的小装饰对象,这样就造成系统可维护性的下降
5.相关讨论
Decorator 模式提供了一种动态为类扩展功能的方法,有着较广的应用
同其他模式一样,滥用 Decorator 会降低系统的可维护性。如果开发出来的装饰类仅被单一的地方使用或只进行了相当简单的处理,就需要考虑是否有必要使用 Decorator 模式了
Facade/Session Facade 模式
1.模式名称
Facade 模式,又称外观模式,也有人很形象地把它翻译成“门面模式”
2.意图解决的问题
在程序中,经常会用到其他若干个子系统。在不作任何处理的时候,需要了解每一个子系统的接口,并使用这些接口进行调用,于是系统就如图所示一样混乱。这些调用不但让结构变得混乱,客户程序和各子系统的耦合性也大大增加,扩展与维护都变得相当困难
3.模式描述
Facade 模式通过在原有系统前增加一层的方法,封装这些子系统的接口,对外提供一致的访问接口,解决了上面的问题
4.效果
Facade 模式屏蔽了子系统的细节,降低了客户程序使用这些子系统的复杂度,同时也降低了客户程序和子系统的耦合程度。这样就从需要让所有的人了解所有的子系统接口变成让个别专家抽象子系统的接口
5.相关讨论
Facade 模式很好地体现了封装的思想,它封装的是一个子系统的内部结构
在 EJB 开发领域,又根据 Facade 模式引申出 Session Facade 模式
通常使用Session Bean 封装这些业务逻辑,提高访问效率,减少内部业务逻辑和外部访问者的耦合,封装服务器中的对象模型
在 Session Facade 模式中,一般使用 Session Bean 作为业务逻辑的接口,在 SessionBean 中进行事务处理,确保客户对 SessionBean 的每一次访问即完成一次业务操作。使用Session Facade 模式除了获得 Facade 模式的优点外,还可以减少远程调用 EJB 的次数,降低网络接口的负载,提高性能
Mediator 模式
1.模式名称
Mediator 模式,又称中介者模式
2.意图解决的问题
在一个复杂系统中会有很多对象,这些对象之间会相互通信,从而造成对象的相互依赖。修改其中一个对象可能会影响到其他若干对象,系统中对象的复杂耦合关系造成系统可维护性的降低,系统显得混乱且难以理解。Mediator 通过封装一组对象间的通信为系统解耦
3.模式描述
在 Mediator 模式中,一组对象 ——抽象类 Colleague 的子类,通过中介类 ——
ConcreteMediator 进行通信,中介类 ConcreteMediator 继承了抽象类 Mediator,其中需要实现 Mediator 中定义的通信接口,保证中介类和相互通信类之间接口的一致
4.效果
Mediator 封装了一组对象间的通信,降低了 Colleague 之间的耦合性,单个 Colleague的变化不会影响到其他的对象
5.相关讨论
Mediator 模式在 GUI 方面有较多的使用。当一个窗体或表单或对话框中有多个需要互相通信的对象时——例如显示部门中人员的下拉列表需要根据部门下拉列表不同的选择而变化,使用 Mediator 封装通信可以降低这些对象的耦合性,提高系统的可维护性
Observer 模式
1.模式名称
Observer 模式,又称观察者模式
2.意图解决的问题
由于对象封装的特性,一般的,在系统中对象状态的变化都是独立的,即 A 对象状态的变化不会立即反映到 B 对象。但是,在系统中很多对象是相互关联的,例如对于一个股票行情系统,股票状态的变化需要同时反映到多个视图中——实时行情、技术分析图表等。对于这个问题,最简单的解决办法就是硬编码这些关联关系。但是这样会造成系统中对象的紧密耦合,系统难以维护和复用
3.模式描述
抽象类 Subject 定义了主题类——也就是被观察者的接口,它的子类 ConcreteSubject的任何状态改变将会通知全部的观察者——ConcreteObserver。为了保持接口的一致性,这些观察者继承自相同的抽象类 Observer。
抽象类在 Subject 中保存有观察者的列表——observers,并通过 attach 和 detach 方法来动态地添加或移出一个特定的观察者。这种采用订阅方法来添加的观察者并不知道还有其他的观察者,它仅仅能够接收被观察的主题对象的状态改变。在 notify 方法中,主题类将根据目前加入订阅的观察者列表 observers 来向每一个观察者发出状态改变的消息
ConcreteSubject 中的 setState()方法表明对象的状态发生了变化,该方法会调用 notify方法对所有的观察者进行更新
4.效果
在 Observer 模式中,实现了具体对象和观察者之间的抽象耦合。虽然 Subject 了解目前有哪些观察者需要捕获自己状态的变化,但它并不了解这些观察者要做什么;而每一个观察者仅仅知道自己捕获到对象的变化,但并不清楚目前有多少观察者在观察对象的状态,也不需要通知其他的观察者。这样,动态的增加和移除观察者是非常简单的
5.相关讨论
Observer 模式将一对多的对象依赖转化为抽象耦合,提高系统的复用价值,得到了广泛的应用
Intercepting Filter 模式
1.模式名称
Intercepting Filter 模式,又称筛选器模式
2.意图解决的问题
在使用 MVC 架构进行 Web 应用开发时,通常需要对来自于客户的请求进行一些预处理,如验证客户身份、验证请求来源、对请求解码等,然后再传递给控制器。如果把这些预处理都交由控制器来完成,将增加控制器的复杂度,而且难以维护和扩展
3.模式描述
FilterManager 负责调度整个 FilterChain,它将在请求到达 Target 前拦截请求,并传递给 FilterChain,由 FilterChain 中的过滤器依次进行预处理。直到请求经过最后一个过滤器后才完成了全部的预处理,然后由 FilterManger 把请求转发给实际的目标
4.效果
使用 Intercepting Filter 模式使得预处理的逻辑和真正的处理逻辑分离,进行实际处理的 Target 只需要关心具体的逻辑,而同请求相关的预处理都放在 FilterManager 中进行。同时解除了这两类处理的耦合性,扩展、修改预处理过程变得容易,系统具有更好的维护性和扩展性
5.相关讨论
设计模式总结
详细讨论了 7 种设计模式:Abstract Factory、Singleton、Decorator、Facade/SessionFacade、Mediator、Observer 和 Intercepting Filter。目前总结出的设计模式远远不止这些,除了 23 种 GoF 模式外,很多学者都在这方面进行了有益的尝试,总结出了大量良好设计的范例
0 条评论
下一页