设计模式部分总结
1.设计原则
-
目标:开闭原则
-
指导:最小知识原则
-
基础:单一职责原则、可变性封装原则
-
实现:依赖倒转原则、合成复用原则、里氏代换原则、接口隔离原则
1.1 单一职责原则(Single Responsibility Principle, SRP)
一个对象应该只包含单一的职责,并且该职责被完整地封装在一个类中。
实例:
变为:
1.2 开闭原则(Open-Closed Principle, OCP)
一个软件实体应当对扩展开放,对修改关闭。也就是说在设计一个模块的时候,应当使这个模块可以在不被修改的前提下被扩展,即实现在不修改源代码的情况下改变这个模块的行为。
可以通过可变性封装原则(Principle of Encapsulation of Variation, EVP)来描述(见1.8补充)
实例:
-
现对该系统进行重构,使之满足开闭原则的要求:尝试将代码变为数据(配置文件,Config.xml),结合Java的反射机制来完成
1.3 里氏代换原则(Liskov Substitution Principle, LSP)
所有引用基类的地方必须能透明地使用其子类的对象。
在程序中尽量使用基类类型来对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对象
实例:
也可以为CipherA和CipherB设计一个共同的父类,下面是指CipherB是在CipherA的基础上加密。
1.4 依赖倒转原则(Dependence Inversion Principle, DIP)
高层模块不应该依赖低层模块,它们都应该依赖抽象。抽象不应该依赖于细节,细节应该依赖于抽象
代码要依赖于抽象的类,而不要依赖于具体的类;要针对接口或抽象类编程,而不是针对具体类编程。
实例:
1.5 接口隔离原则(Interface Segregation Principle, ISP)
客户端不应该依赖那些它不需要的接口。一旦一个接口太大,则需要将它分割成一些更细小的接口,使用该接口的客户端仅需知道与之相关的方法即可。
实例:
1.6 合成复用原则(Composite Reuse Principle, CRP)
尽量使用对象组合,而不是继承来达到复用的目的。
ps:聚合和组合的区别
-
聚合是独立的,组合局部不能离开总体(往往只属于一个组合对象,组合关系更强)。
-
聚合是空心菱形箭头,组合是实心菱形箭头
1.7 迪米特法则(Law of Demeter, LoD)
又称为最少知识原则(Least Knowledge Principle, LKP)。
几种定义:
-
不要和"陌生人"说话。英文定义为:Don't talk to strangers.
-
只与你的直接朋友通信。英文定义为:Talk only to your immediate friends.
-
每一个软件单位对其他的单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位。英文定义为:Each unit should have only limited knowledge about other units: only units "closely" related to the current unit.
实例:
1.8 可变性封装原则(补充)(Principle of Encapsulation of Variation, EVP)
-
一种可变性不应当散落在代码的很多角落里,而应当被封装到一个对象里面。继承应当被看做是封装变化的方法,而不应当被认为是从一般的对象生成特殊的对象方法。
-
一种可变性不应当与另一种可变性混合在一起。所有的类图的继承结构一般不会超过两层,不然就意味着将两种不同的可变性混合在一起。
2. 设计模式
软件模式的定义
软件模式是将模式的一般概念应用于软件开发领域,即软件开发的总体指导思路或参照样板。软件模式并非仅限于设计模式,还包括架构模式、分析模式和过程模式等,实际上,在软件生存期的每一个阶段都存在着一些被认同的模式。
软件模式可以认为是对软件开发这一特定“问题”的“解法”的某种统一表示,软件模式等于一定条件下的出现的问题以及解法。软件模式的基础结构由4个部分构成:问题描述、前提条件(环境或约束条件)、解法和效果。
设计模式的定义
设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结,使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。
设计模式的基本要素:
-
模式名称:注意别名
-
问题
-
解决方案:画个uml图?
-
效果(Consequences):优缺点
设计模式的分类
-
根据目的,可以分为:
-
创建型(Creational):主要用于创建对象
-
结构型(Structural):主要用于处理类或对象的组合
-
行为型(Behavioral):主要用于描述对类或对象怎样交互和怎样分配职责
-
-
根据范围,可以分为:
-
类模式:处理类和子类之间的关系,这些关系通过继承建立,在编译时刻就被确定下来,属于静态的。
-
对象模式:处理对象间的关系,这些关系在运行时刻变化,更具动态性。
-
考试范围
1. 策略模式
对象行为型模式
体现:开闭原则、依赖倒转原则、合成复用原则
(1)名称及别名
名称:策略模式(Strategy Pattern)
别名:Policy Pattern
(2)问题域(模式动机)
?
-
存在许多用于将文本流分成行的算法。将所有这样的算法硬连接到类中是不可取的。
-
不满足开闭原则,每次修改都要反复检查每一个条件语句
(3)解决方案
定义一系列算法,封装每个算法,并使它们可替换。策略使算法可以独立于使用该算法的客户端而变化。
1)模式结构
-
Context:上下文
-
Strategy:抽象策略
-
ConcreteStrategy:具体策略
2)模式类图
(4)效果
1)优点
-
消除条件语句
-
策略可以提供相同行为的不同实现。客户可以选择具有不同时间和空间权衡的策略
2)缺点
-
客户在选择合适的策略之前必须先了解策略的不同
-
策略和上下文之间的通信开销
-
对象数量增加
模式一般都会有的缺点:
-
增加设计的复杂度和增加类的个数
-
增加隔阂、方法调用,降低软件运行的效率,但是这不是主要问题
(5)适用环境
-
许多相关的类仅在行为上有所不同
-
需要算法的不同变体
-
可避免暴露复杂的、特定于算法的数据结构
-
一个类定义了许多行为,这些行为在其操作中显示为多个条件语句。代替许多条件,将相关的条件分支移到他们自己的策略类中。
2.工厂方法模式
类创建型模式
单一职责原则、开闭原则
(1)名称及别名
名称:Factory Method Pattern
别名:Virtual Constructor, Polymorphic Factory
(2)问题域(模式动机)
考虑这样一个系统,按钮工厂类可以返回一个具体的按钮实例,如圆形按钮、矩形按钮、菱形按钮等。在这个系统中,如果需要增加一种新类型的按钮,如椭圆形按钮,那么除了增加一个新的具体产品类之外,还需要修改工厂类的代码,这就使得整个设计在一定程度上违反了"开闭原则"。
(3)解决方案
工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。
1)模式结构
2)模式类图
(4)效果
1)优点
-
用户只需要关心所需产品对应的工厂,无须关心创建细节,甚至无需知道具体产品类的类名
-
工厂可以自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部
-
加入新产品时,无需修改抽象工厂和抽象产品提供的结构,无需修改客户端,也无需修改其他的具体工厂和具体产品,只要添加一个具体工厂和具体产品就可以了。
2)缺点
-
需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,增加了系统的复杂度
-
增加了系统的抽象性和理解难度
(5)适用环境
-
一个类不知道它所需要的对象的类
-
一个类通过其子类来指定创建哪个对象
-
将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无须关心是哪一个工厂子类创建产品子类,需要时再动态指定
-
希望能够推迟创建时
3. 抽象工厂模式
对象创建型
(1)名称及别名
名称:Abstract Factory Pattern
(2)问题域(模式动机)
-
产品等级结构:产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类有海尔电视机、海信电视机、TCL电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而具体品牌的电视机是其子类。
-
产品族:在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品,如海尔电器工厂生产的海尔电视机、海尔电冰箱,海尔电视机位于电视机产品等级结构中,海尔电冰箱位于电冰箱产品等级结构中。
当系统所提供的工厂所需生产的具体产品并不是一个简单的对象,而是多个位于不同产品等级结构中属于不同类型的具体产品时需要使用抽象工厂模式。抽象工厂模式是所有形式的工厂模式中最为抽象和最具一般性的一种形态。
(3)解决方案
1)模式结构
-
AbstractFactory:抽象工厂
-
ConcreteFactory:具体工厂
-
AbstractProduct:抽象产品
-
Product:具体产品
2)模式类图
(4)效果
1)优点
-
隔离了具体类的生成,只需要改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。因此可以实现高内聚低耦合的设计目的。
-
能够保证客户端始终只使用同一个产品族中的对象
-
增加新的具体工厂和产品族很方便,无需修改已有系统,符合“开闭原则”
2)缺点
-
难以扩展抽象工厂来生产新种类的产品,即:增加新的工厂和产品组容易,增加新的产品等级结构麻烦
(5)适用环境
-
一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节
-
有多于一个产品组,而每次只使用其中某一产品组
-
属于同一个产品族的产品将在一起使用
-
所有产品以同样的接口出现
4. 状态模式
(1)名称及别名
名称:State Pattern
(2)问题域(模式动机)
在很多情况下,一个对象的行为取决于一个或多个动态变化的属性,这样的属性叫做状态,这样的对象叫做有状态的(stateful)对象,这样的对象状态是从事先定义好的一系列值中取出的。当一个这样的对象与外部事件产生互动时,其内部状态就会改变,从而使得系统的行为也随之发生变化。
(3)解决方案
1)模式结构
-
Context: 环境类
-
State: 抽象状态类
-
ConcreteState: 具体状态类
ps:在结构上和策略模式是一致的,但是使用上是很不同的,最大的区别在于setStrategy(在client实现)和setState(在模式中实现)在哪个地方实现。策略模式需要暴露策略细节,由client来选择合适策略;状态模式下,状态的设置由模式自己来完成的,对客户是透明的,看上去是状态改变了自己。
2)模式类图
(4)效果
1)优点
-
封装了转换规则
-
枚举可能的状态
-
方便地增加新的状态
-
允许状态转换逻辑与状态对象合成一体
-
可以让多个环境对象共享一个状态对象,减少系统中对象的个数。
2)缺点
-
增加系统类和对象的个数
-
如果使用不当将导致程序结构和代码的混乱
-
对“开闭原则”的支持并不太好
(5)适用环境
-
对象的行为依赖于它的状态(属性)并且可以根据它的状态改变而改变它的相关行为
-
代码中包含大量与对象状态有关的条件语句
5. 命令模式
对象行为型
(1)名称及别名
名称:Command Pattern
别名:Action Pattern, Transaction Pattern
(2)问题域(模式动机)
在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计,使得请求发送者与请求接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活。
(3)解决方案
将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。命令模式是一种对象行为型模式,其别名为动作(Action)模式或事务(Transaction)模式。
1)模式结构
-
Command: 抽象命令类
-
ConcreteCommand: 具体命令类
-
Invoker: 调用者
-
Receiver: 接收者
-
Client:客户类
2)模式类图
顺序图:
(4)效果
1)优点
-
降低系统的耦合度
-
新的命令可以很容易地加入到系统中
-
可以比较容易地设计一个命令队列和宏命令
-
可以方便地实现对请求的Undo和Redo
2)缺点
-
可能会导致某些系统有过多的具体命令类
(5)适用环境
-
需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互
-
需要在不同的时间指定请求、将请求排队和执行请求
-
需要支持命令的撤销操作和恢复操作
-
需要将一组操作组合在一起,即支持宏命令
6. 观察者模式
对象行为型模式
(1)名称及别名
名称:Observer Pattern
别名:Publish/Subscribe, Model/View, Source/Listener, Dependents
(2)问题域(模式动机)
-
建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应做出反应。
-
发生改变的对象称为观察目标
-
被通知的对象称为观察者
-
-
一个观察目标可以对应多个观察者,而且这些观察者之间没有相互联系,可以根据需要增加和删除观察者,使得系统更易于扩展,这就是观察者模式的模式动机。
(3)解决方案
1)模式结构
-
Subject: 目标
-
ConcreteSubject: 具体目标
-
Observer: 观察者
-
ConcreteObserver: 具体观察者
2)模式类图
顺序图:
(4)效果
1)优点
-
可以实现表示层和数据逻辑层的分离
-
可以在观察目标和观察者之间建立一个抽象的耦合
-
支持广播通信
-
符合开闭原则的要求
2)缺点
-
一个观察目标有很多直接和间接观察者的话,将所有观察者都通知到会话很多时间
-
在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃
-
没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
(5)适用环境
-
一个抽象模型有两个方面,其中一个方面依赖于另一个方面,这些方面封装在独立的对象中使它们可以各自独立地改变和复用
-
一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变
-
一个对象必须通知其他对象,而并不知道这些对象是谁
-
需要在系统中创建一个触发链
7. 中介者模式
满足迪米特法则
(1)名称及别名
名称:Mediator Pattern
(2)问题域(模式动机)
-
在用户与用户直接聊天的设计方案中,用户对象之间存在很强的关联性,将导致系统出现如下问题:
-
系统结构复杂:对象之间存在大量的相互关联和调用,若有一个对象发生变化,则需要跟踪和该对象关联的其他所有对象,并进行适当处理。
-
对象可重用性差:由于一个对象和其他对象具有很强的关联,若没有其他对象的支持,一个对象很难被另一个系统或模块重用,这些对象表现出来更像一个不可分割的整体,职责较为混乱。
-
系统扩展性低:增加一个新的对象需要在原有相关对象上增加引用,增加新的引用关系也需要调整原有对象,系统耦合度很高,对象操作很不灵活,扩展性差。
-
-
在面向对象的软件设计与开发过程中,根据“单一职责原则”,我们应该尽量将对象细化,使其只负责或呈现单一的职责。
-
对于一个模块,可能由很多对象构成,而且这些对象之间可能存在相互的引用,为了减少对象两两之间复杂的引用关系,使之成为一个松耦合的系统,我们需要使用中介者模式,这就是中介者模式的模式动机。
(3)解决方案
用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。中介者模式又称为调停者模式,它是一种对象行为型模式。
1)模式结构
-
Mediator: 抽象中介者
-
ConcreteMediator: 具体中介者
-
Colleague: 抽象同事类
-
ConcreteColleague: 具体同事类
2)模式类图
(4)效果
1)优点
-
简化了对象之间的交互
-
将各同事解耦
-
减少子类的生成
-
简化各同事类的设计和实现
2)缺点
-
在具体中介者类中包含了同事之间的交互细节,可能会导致具体中介者类非常复杂,难以维护
(5)适用环境
-
系统中对象之间存在复杂的引用关系,产生的相互依赖关系结构混乱且难以理解
-
一个对象由于引用了其他很多对象并且直接和这些对象通信,导致难以复用该对象
-
想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类
8. 模板方法模式
开闭原则,单一职责原则
类行为型模式
(1)名称及别名
名称:Template Method Pattern
(2)问题域(模式动机)
在模板方法模式中,我们需要准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来让子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现,这就是模板方法模式的用意。模板方法模式体现了面向对象的诸多重要思想,是一种使用频率较高的模式。
(3)解决方案
定义一个操作中算法的骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。模板方法是一种类行为型模式。
1)模式结构
-
AbstractClass: 抽象类
-
ConcreteClass: 具体子类
2)模式类图
(4)效果
1)优点
-
在一个类中抽象地定义算法,而由它的子类实现细节的处理
-
是一种代码复用的基本技术
-
导致一种反向的控制结构,符合“开闭原则”
2)缺点
-
每个不同的实现都需要定义一个子类,导致类的个数增加
(5)适用环境
-
一次性实现一个算法的不变的部分,将可变的行为留给子类来实现
-
各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复
-
对一些复杂的算法进行分割
-
控制子类的扩展
9. (类)适配器模式
类结构型
名称:Adapter Pattern
别名:Wrapper
(1)名称及别名
(2)问题域(模式动机)
(3)解决方案
将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。
1)模式结构
-
Target:目标抽象类
-
Adapter:适配器类
-
Adaptee:适配者类
-
Client:客户类
2)模式类图
(4)效果
1)优点
公共:
-
将目标类和适配者类解耦
-
增加了类的透明性和复用性
-
灵活性和扩展性都非常好
类适配器:
-
由于适配器类是适配者类的子类,可以在适配器类中置换一些适配者的方法,使适配器的灵活性更强
2)缺点
-
有些语言不支持多重继承,一次最多只能适配一个适配者类,而且目标抽象类只能为抽象类,不能为具体类,具有一定局限性
(5)适用环境
-
系统需要使用现有的类,但接口不符合系统的需要
-
想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类
10. (对象)适配器模式
对象结构型
(1)名称及别名
同上
(2)问题域(模式动机)
同上
(3)解决方案
1)模式结构
同上
2)模式类图
(4)效果
1)优点
公共:同上
对象适配器:
-
同一个适配器可以把适配者类和它的子类都适配到目标接口
2)缺点
-
想要置换适配者类的方法并不容易
(5)适用环境
同上
11. 组合模式
对象结构型
(1)名称及别名
名称:Composite Pattern
别名:Part-Whole
(2)问题域(模式动机)
-
对于树形结构,当容器对象(如文件夹)的某一个方法被调用时,将遍历整个树形结构,寻找也包含这个方法的成员对象(可以是容器对象,也可以是叶子对象,如子文件夹和文件)并调用执行。(递归调用)
-
由于容器对象和叶子对象在功能上的区别,在使用这些对象的客户端代码中必须有区别地对待容器对象和叶子对象,而实际上大多数情况下客户端希望一致地处理它们,因为对于这些对象的区别对待将会使得程序非常复杂。
-
组合模式描述了如何将容器对象和叶子对象进行递归组合,使得用户在使用时无须对它们进行区分,可以一致地对待容器对象和叶子对象,这就是组合模式的模式动机。
(3)解决方案
组合多个对象形成树形结构以表示"整体-部分"的结构层次。组合模式对单个对象(即叶子对象)和组合对象(即容器对象)的使用具有一致性。
1)模式结构
-
Component: 抽象构件
-
Leaf: 叶子构件
-
Composite: 容器构件
-
Client: 客户类
2)模式类图
(4)效果
1)优点
-
可以清楚地定义分层次的复杂对象
-
客户端可以一致地使用组合结构或其中单个对象
-
可以形成复杂的树形结构
-
更容易在组合体内加入对象构件
2)缺点
-
使设计变得更加抽象
-
很难对容器中的构建类型进行限制
(5)适用环境
-
需要表示一个对象整体或部分层次
-
客户端可以针对抽象构建编程,无需关心对象层次结构的细节
-
对象的结构是动态的,并且复杂程度不一样,但客户需要一直地处理它们。
12. 装饰模式
对象结构型
(1)名称及别名
名称:Decorator Pattern
别名:Wrapper
(2)问题域(模式动机)
-
一般有两种方式可以实现给一个类或对象增加行为:
-
继承机制,使用继承机制是给现有类添加功能的一种有效途径,通过继承一个现有类可以使得子类在拥有自身方法的同时还拥有父类的方法。但是这种方法是静态的,用户不能控制增加行为的方式和时机。
-
关联机制,即将一个类的对象嵌入另一个对象中,由另一个对象来决定是否调用嵌入对象的行为以便扩展自己的行为。
-
-
装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任,换言之,客户端并不会觉得对象在装饰前和装饰后有什么不同。装饰模式可以在不需要创造更多子类的情况下,将对象的功能加以扩展。这就是装饰模式的模式动机。
(3)解决方案
动态地给一个对象增加一些额外的职责(Responsibility),就增加对象功能来说,装饰模式比生成子类实现更为灵活。其别名也可以称为包装器(Wrapper),与适配器模式的别名相同,但它们适用于不同的场合。根据翻译的不同,装饰模式也有人称之为"油漆工模式",它是一种对象结构型模式。
1)模式结构
-
Component: 抽象构件
-
ConcreteComponent: 具体构件
-
Decorator: 抽象装饰类
-
ConcreteDecorator: 具体装饰类
2)模式类图
(4)效果
1)优点
-
可以提供比继承更多的灵活性
-
可以通过一种动态的方式来扩展一个对象的功能
-
通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合
-
具体构件类与具体装饰类可以独立变化
2)缺点
-
将产生很多小对象
-
比继承更加容易出错,排错也很困难
(5)适用环境
-
以动态、透明的方式给单个对象添加职责
-
需要动态地给一个对象增加功能,这些功能也可以动态地被撤销
-
当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时
13. 外观模式
迪米特法则
对象结构型
(1)名称及别名
名称:Facade Pattern
(2)问题域(模式动机)
(3)解决方案
外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。外观模式又称为门面模式,它是一种对象结构型模式。
1)模式结构
-
Facade: 外观角色
-
SubSystem:子系统角色
2)模式类图
(4)效果
1)优点
-
对客户屏蔽子系统组件,减少了客户处理的对象数目并使得子系统使用起来更加容易
-
实现了子系统与客户之间的松耦合关系
-
降低了大型软件系统中的编译依赖性,并简化了系统在不同平台之间的移植过程
-
只是提供了一个访问子系统的统一入口,并不影响用户直接使用子系统类
2)缺点
-
不能很好地限制客户使用子系统类
-
在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”
(5)适用环境
-
当要为一个复杂子系统提供一个简单接口时可以使用外观模式
-
客户程序与多个子系统之间存在很大的依赖性
-
层次化系统中,可以使用外观模式定义系统中每一层的入口,层与层之间不直接产生联系,而通过外观类建立联系,降低层之间的耦合度
14. 代理模式
对象结构型
迪米特法则
(1)名称及别名
名称:Proxy Pattern
别名:Surrogate Pattern
(2)问题域(模式动机)
在某些情况下,一个客户不想或者不能直接引用一个对象,此时可以通过一个称之为“代理”的第三者来实现间接引用。代理对象可以在客户端和目标对象之间起到中介的作用,并且可以通过代理对象去掉客户不能看到的内容和服务或者添加客户需要的额外服务。
(3)解决方案
给某一个对象提供一个代理,并由代理对象控制对原对象的引用。
1)模式结构
-
Subject: 抽象主题角色
-
Proxy: 代理主题角色
-
RealSubject: 真实主题角色
2)模式类图
(4)效果
1)优点
-
能够协调调用者和被调用者,在一定程度上降低了系统的耦合度
-
使得客户端可以访问在远程机器上的对象
-
虚拟代理通过使用小对象来代表大对象,可以减少系统资源的消耗
-
保护代理可以控制对真实对象的使用权限
2)缺点
-
可能造成请求的处理速度变慢
-
需要额外的工作,实现会变得复杂
(5)适用环境
用户不能直接访问真实对象。
根据目的,分为:
-
远程(Remote)代理
-
虚拟(Virtual)代理
-
Copy-on-Write代理
-
保护(Protect or Access)代理
-
缓冲(Cache)代理
-
防火墙(Firewall)代理
-
智能引用(Smart Reference)代理
表驱动
Table-Driven Methods
是一种编程模式(scheme)
目标
从表里面查找信息而不使用条件语句
原理
如何快速从表中查询条目
1. 直接访问(Direct access)
通过索引值(如下标)可以直接从表中找到对应的条目