PRELOADER

当前文章 : 《Java23种设计模式》

10/8/2019 —— 

Java设计模式

简单工厂模式

介绍:专门定义一个类去创建其他类的实例,被创建的实例通常具有相同的父类。

相关概念:

1.工厂(Creator) 角色
简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象。

2.抽象(Product) 角色
简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。

3.具体产品(Concrete Product)角色
简单工厂模式所创建的具体实例对象

优缺点

在这个模式中,工厂类是整个模式的关键所在,它包含必要的判断逻辑,能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。用户在使用时可以直接根据工厂类去创建所需的实例,而无需了解这些对象是如何创建以及如何组织的。有利于整个软件体系结构的优化。

不难发现,简单工厂模式的缺点也正体现在其工厂类上,由于工厂类集中了所有实例的创建逻辑,所以“高内聚方面做的并不好。另外,当系统中的具体产品类不断增多时,可能会出现要求工厂类也要做相应的修改,扩展性并不很好。

工厂方法模式

介绍:工厂方法模式同样属于类的创建型模式又被称为多态工厂模式。工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。

相关概念:

1.抽象工厂 (Creator)

角色工厂 方法模式的核心,任何工厂类都必须实现这个接口。

2.具体工厂( Concrete Creator) 角色

具体工厂 类是抽象工厂的一个实现,负责实例化产品对象。

3.抽象(Product) 角色

工厂 方法模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。

4.具体产品(Concrete Product)

角色工厂 方法模式所创建的具体实例对象

与简单工厂模式的对比

工厂方法模式与简单工厂模式在结构上的不同不是很明显。工厂方法类的核心是一一个抽象工厂类,而简单工广模式把核心放在一一个具体类上。
工厂方法模式之所以有一个别名叫多态性工厂模式是因为具体工厂类都有共同的接口,或者有共同的抽象父类。
当系统扩展需要添加新的产品对象时,仅仅需要添加一一个具体对象以及一个具体工厂对象,原有工厂对象不需要进行任何修改,也不需要修改客户端,很好的符合了“开放-封闭”原则。而简单工厂模式在添加新产品对象后不得不修改工厂方法,扩展性不好。
工方法模式退化后叫以演变成间单工模式。

比如要创建苹果,香蕉,梨子,在简单工厂中,要把创建这三种水果放在同一个工厂里面。而现在工厂方法是先创建一个水果工厂的接口,然后再建三个工厂(苹果,香蕉,梨子工厂)实现这个接口,具体创建过程在这三个工厂中,以后要想增加一种水果,只需要创建一个水果对象和一个对应水果的工厂(实现顶层工厂接口),而不用改变顶层的工厂接口。

抽象工厂模式

介绍:抽象工厂模式是所有形态的工厂模式中最为抽象和最其一般性的。抽象工厂模式可以向客户端提供一个接口,使得客户端在不必指定产品的具体类型的情况下,能够创建多个产品族的产品对象。

相关概念:

1.抽象工厂(Creator) 角色

抽象工厂模式的核心,包含对多个产品结构的声明,任何工厂类都必须实现这个

2.具体工厂( Concrete Creator) 角色

具体工厂 类是抽象工厂的一个实现,负责实例化某个产品族中的产品对象。

3.抽象(Product) 角色

抽象模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。

4.具体产品(Concrete Product)角色抽象模式所创建的具体实 例对象

与工厂方法的对比:

抽象工厂引入族和等级。等级:产品的共有属性。顶层的抽象接口,一般不需要更改。族:产品的类别。

假设在工厂方法的基础上我们引入等级的概念(水果分为南方和北方)。新增水果(葡萄为例)时,这时候我们就需要分别创建一个南方葡萄工厂和北方葡萄工厂。而在抽象工厂中,我们把等级抽象到顶层接口地域(南方、北方)增加水果时只需要创建一个工厂并实现地域接口即可。

单例模式

介绍:单例模式是一种对象创建型模式,使用单例模式,可以保证为一-个类只生成唯一的实例对象。也就是说,在整个程序空间中,该类只存在-一个实例对象。
其实,GoF对单例模式的定义是:保证-一个类、只有一一个实例存在, 同时提供能对该实例加以访问的全局访问方法。

相关实现:

  1. 饿汉式
  2. 懒汉式
  3. 双重检查

原型模式

介绍:Prototype模式是一种对象创建型模式,它采取复制原型对象的方法来创建对象的实例。使用Prototype模式创建的实例,具有与原型一样的数据。

特点:

1.由原型对象自身创建目标对象。也就是说,对象创建这一动作发自 原型对象本身。
2.目标对象是原型对象的一个克隆。也就是说,通过Prototype模式创建的对象,不仅仅与原型对象具有相同的结构,还与原型对象具有相同的值。
3.根据对象克隆深度层次的不同,有浅度克隆与深度克隆。

适用场景:

-在创建对象的时候,我们不只是希望被创建的对象继承其基类的基本结构,还希望继承原型对象的数据。
-希望对目标对象的修改不影响既有的原型对象(深度克隆的时候可以完全互不影响)。
-隐藏克隆操作的细节。很多时候,对对象本身的克隆需要涉及到类本身的数据细节。

建造者模式

介绍:Builder模式也叫建造者模式或者生成器模式,是由GoF提出的23种设计模式中的-一种。Builder模式是一种对象创建型模式之一,是将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。它用来隐藏复合对象的创建过程,它把复合对象的创建过程加以抽象,通过子类继承和重载的方式,动态地创建具有复合属性的对象。

适用场景:

-对象的创建:Builder模式是为对象的创建而设计的模式
-创建的是一个复合对象:被创建的对象为一个具有复合属性的复合对象
-关注对象创建的各部分的创建过程:不同的工厂(这里指builder生成器)对产品属性有不同的创建方法

装饰模式

介绍:装饰( Decorator )模式又叫做包装模式。通过一种对客户端透明的方式来扩展对象的功能,是继承关系的一个替换方案。就是在不改变原有对象的情况下,扩展对象的功能。

原理:原始对象—>装饰器—>装饰后的对象

角色和职责:

抽象组件角色: 一个抽象接口,是被装饰类和装饰类的父接口。
具体组件角色:为抽象组件的实现类。
抽象装饰角色:包含一个组件的引用,并定义了与抽象组件一致的接口。
具体装饰角色:为抽象装饰角色的实现类。负责具体的装饰。

策略模式

介绍:Strategy模式也叫策略模式是行为模式之一,它对一系列的算法加以抽象封装,为所有算法定义一个抽象的算法接口,并通过继承该抽象算法接口对所有的算法加以封装和实现(不同类可以有不同的实现),具体的算法选择交由客户端决定(策略)。Strategy模式主要用来平滑地处理算法的切换。

相关概念:

Strategy::策略(算法)抽象。
ConcreteStrategy:各种策略(算法)的具体实现。
Context:策略的外部封装类,或者说策略的容器类。根据不同策略执行不同的行为。策略由外部环境决定。

优点:

1.策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码移到父类里面,从而避免重复的代码。

2.策略模式提供了可以替换继承关系的办法。继承可以处理多种算法或行为。如果不是用策略模式,那么使用算法或行为的环境类就可能会有一些子类,每一个子类提供一个不同的算法或行为。但是,这样一来算法或行为的使用者就和算法或行为本身混在一起。决定使用哪一种算法或采取哪-种行为的逻辑就和算法或行为的逻辑混合在一起,从而不可能再独立演化。继承使得动态改变算法或行为变得不可能。

3.使用策略模式可以避免使用多重条件转移语句。多重转移语句不易维护,它把采取哪种算法或采取哪-种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重转移语句里面,比使用继承的办法还要原始和落后。

缺点:

1.客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道所有的算法或行为的情况。

2.策略模式造成很多的策略类。有时候可以通过把依赖于环境的状态保存到客户端里面,而将策略类设计成可共享的,这样策略类实例可以被不同客户端使用换言之,可以使用享元模式来减少对象的数量。

观察者模式

介绍

Observer模式是行为模式之一,它的作用是当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态。

Observer模式提供给关联对象一种同步通信的手段,使某个对象与依赖它的其他对象之间保持状态同步。

相关概念:

Subjest被观察的对象。当需要被观察的状态发生变化时,需要通知队列中所(被观察者)
有观察者对象。Subject需要维持(添加,珊除,通知)一个 观察者对象的队列列表。

Concrete Subject,被观察者的具体实现。包含些基本的属性状态及其他操作。

Obseryer (观察者)接口或抽象类。当Subject的状态发生变化时, Observer对 象将通过一个callback函数得到通知。

ConcreteObserver观察者的具体实现。得到通知后将完成一些具 体的业务逻辑处理。

典型应用
-侦听事件驱动程序设计中的外部事件-侦听/监视某个对象的状态变化
-发布者/订阅者(publisher/subscriber)模型中,当一个外部事件(新的产品,消息的出现等等)被触发时,通知邮件列表中的订阅者

享元模式

介绍:Flyweight模式也叫享元模式,是构造型模式之一,它通过与其他类似对象共享数据来减小内存占用。

相关概念:

抽象享元角色:
所有具体享元类的父类,规定一些需要实现的公共接口。

具体享元角色:
抽象享元角色的具体实现类,并实现了抽象享元角色规定的方法。

享元工厂角色:
负责创建和管理享元角色。

举例:

String常量池、数据库连接池、缓冲池等等都是享元模式的应用

代理模式

介绍:Proxy模式又叫做代理模式,是构造型的设计模式之一,它可以为其他对象提供一种代理(Proxy) 以控制对这个对象的访问。

所谓代理,是指具有与代理元(被代理的对象)具有相同的接口的类,客户端必须通过代理与被代理的目标类交互,而代理一般在交互的过程中(交互前后),进行某些特别的处理。

相关概念:

subject (抽象主题角色) :
真实主题与代理主题的共同接口。

RealSubject (真实主题角色) :
定义了代理角色所代表的真实对象。

Proxy (代理主题角色) :
含有对真实主题角 色的引用,代理角色通常在将客户端调用传递给真是主题对象之前或者之后执行某些操作,而不是单纯返回真实的对象。

动态代理:不用再手动创建代理对象

外观模式

介绍: 外观模式是一种使用频率非常高的结构型设计模式,它通过引入一个外观角色来简化客户端与子系统之间的交互,为复杂的子系统调用提供一个统一的入口,降低子系统与客户端的耦合度,且客户端调用非常方便。

相关概念:

Facade
为调用方定义简单的调用接口。
Clients
调用者。通过Facade接口调用提供某功能的内部类群。
Packages
功能提供者。指提供功能的类群(模块或子系统)。

举例:

比如吃饭。你自己做着吃的话就必须了解做各种饭的各种方法、步骤、细节。而你去餐馆吃,只需要告诉服务员你吃什么就可以了,这里的餐馆就相当于外观模式。

组合模式

介绍:将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

相关概念:

Component ( 树形结构的节点抽象)
.为所有的对象定义统一-的接口(公共属性,行为等的定义).提供管理子节点对象的接口方法
. [可选]提供管理父节点对象的接口方法

Leaf (树 形结构的叶节点)Component的实现子类

Composite (树形结构的枝节点)Component的实现子类

适用场景:

当发现需求中是体现部分与整体层次结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑组合模式了。

举例:

组合模式容器和内容具有一致性,可以进行递归操作。比如文件和文件夹。

桥接模式

介绍:Bridge模式又叫做桥接模式,是构造型的设计模式之一。Bridge模式基于类的最小设计原则,通过使用封装,聚合以及继承等行为来让不同的类承担不同的责任。它的主要特点是把抽象(abstraction) 与行为实现(implementation)分离开来,从而可以保持各部分的独立性以及应对它们的功能扩展。

将抽象部分与它的实现部分分离,使它们都可以独立地变化。

相关概念:

Client

Bridge模式的使用者Abstraction

抽象类接口(接口或抽象类)

维护对行为实现( lmplementor)的引用Refined Abstraction

Abstraction子类Implementor

行为实现类接口(Abstraction接口定义了基于lmplementor接口的更高层次的操作)Concretelmplementor

Implementor子类

举例:
增加一款新的手机软件,需要在所有手机品牌类下添加对应的手机软件类,当手机软件种类较多时,将导致类的个数急剧膨胀,难以维护。

手机和手机中的软件是什么关系?

手机中的软件从本质上来说并不是一种手机,手机软件运行在手机中,是一种包含与被包含关系,而不是一种父与子或者说一般与特殊的关系,通过继承手机类实现手机软件类的设计是违反一般规律的。

如果Oppo手机实现了wifi功能,继承它的Oppo应用商城也会继承wifi功能,并且Oppo手机类的任何变动,都会影响其子类换一种解决思路。

从类图上看起来更像是手机软件类图,涉及到手机本身相关的功能,比如说:wifi功能,放到哪个类中实现呢?放到OppoAppStore中实现显然是不合适的引起整个结构变化的元素有两个,一个是手机品牌,一个是手机软件,所以我们将这两个点抽出来,分别进行封装对比最初的设计,将抽象部分(手机)与它的实现部分(手机软件类)分离,将实现部分抽象成单独的类,使它们都可以独立地变化。整个类图看起来像一座桥,所以称为桥接模式

适配器模式

介绍:Adapter模式也叫透配器模式,是杓造型模式之一通辻Adapter模式可以改変已有炎(或外部炎)的接口形式。

实现方式:

  • 通过继承来实现
  • 通过委让来实现

适用场景:在大规模的系统开发过程中,我们常常碰到诸如以下这些情况:我们需要实现某些功能,这些功能已有还不太成熟的一个或多个外部组件,如果我们自己重新开发这些功能会花费大量时间;所以很多情况下会选择先暂时使用外部组件,以后再考虑随时替换。但这样一来,会带来一个问题,随着对外部组件库的替换,可能需要对引用该外部组件的源代码进行大面积的修改,因此也极可能引入新的问题等等。如何最大限度的降低修改面呢?Adapter模式就是针对这种类似需求而提出来的。

Adapter模式通过定义一一个新的接口(对要实现的功能加以抽象),和一个实现该接口的Adapter (适配器)类来透明地调用外部组件。这样替换外部组件时,最多只要修改几个Adapter类就可以了,其他源代码都不会受到影响。

解释器模式

介绍:Interpreter模式也叫解释器模式,是行为模式之一,它是一种特殊的设计模式,它建立一个解释器,对于特定的计算机程序设计语言,用来解释预先定义的文法。简单地说,Interpreter模式是 一种简单的语法解释器构架。

相关概念:

Context
解释器上下文环境类。用来存储解释器的.上下文环境,比如需要解释的文法等。
AbstractExpression
解释器抽象类。
ConcreteExpression
解释器具体实现类。

适用场景:

● 当有一个语言需要解释执行,并且你可将该语言中的句子表示

为一个抽象语法树时,可使用解释器模式。而当存在以下情况时该模式效果最好:

● 该文法简单对于复杂的文法,文法的类层次变得庞大而无法管

理。此时语法分析程序生成器这样的工具是更好的选择。它们无需构建抽象语法树即可解释表达式,这样可以节省空间而且还可能节省时间。

● 效率不是一个关键问题,最高效的解释器通常不是通过直接

解释语法分析树实现的,而是首先将它们转换成另一种形式。例如,正则表达式通常被转换成状态机。但即使在这种情况下,转换器仍可用解释器模式实现,该模式仍是有用的。

可用于基于Java的自定义语言进行解析。

中介模式

介绍:中介者模式就是用一个中介者封装所有的调用对象,然后用户通过中介者来调用相应的功能,并不需要其它各个类之间相互包含引用,这样可以达到松耦合的目的。中介者对象起着控制器的作用。

相关概念:

mediator
中介者类的抽象父类。

concrete Mediator
具体的中介者类。

colleague
关联类的抽象父类。

concreteColleague
具体的关联类。

优点:

1,将系统按功能分割成更小的对象,符合类的最小设计原则

2,对关联对象的集中控制

3,减小类的耦合程度,明确类之间的相互关系:当类之间的关系过于复杂时,其中任何一个类的修改都会影响到其他类,不符合类的设计的开闭原则,而Mediator模式将原来相互依存的多对多的类之间的关系简化为Mediator控制类与其他关联类的一对多的关系,当其中一个类修改时,可以对其他关联类不产生影响(即使有修改,也集中在Mediator控制类) 。

4,有利于提高类的重用性

责任链模式

介绍:Chain of Responsibility (CoR)模式也叫职责链模式或者职责连锁模式,是行为模式之一,该模式构造一系列分别担当不同的职责的类的对象来共同完成一个任务,这些类的对象之间像链条一样紧密相连,所以被称作职责链模式。

其将链中每一个节点看作是一个对象,每个节点处理的请求均不同,且内部自动维护一个下一节点对象。当一个请求从链式的首端发出时,会沿着链的路径依次传递给每一个节点对象,直至有对象处理这个请求为止。

相关概念:

Handler
处理类的抽象父类。

concreteHandler
具体的处理类。

例子:比如客户Client要完成一个任务,这个任务包括a,b,c,d四个部分。

首先客户Client把任务交给A,A完成a部分之后,把任务交给B,B完成b部分,. 直到D完成d部分。

例2:比如政府部分的某项工作,县政府先完成自己能处理的部分,不能处理的部分交给省政府,省政府再完成自己职责范围内的部分,不能处理的部分交给中央政府,中央政府最后完成该项工作。例3:软件窗口的消息传播。

例4: SERVLET容器的过滤器(Filter) 框架实现。

实现条件:

要实现Chain of Responsibility模式,需要满足该模式的基本条件:

1,对象链的组织。需要将某任务的所有职责执行对象以链的形式加以组织。

2,消息或请求的传递。将消息或请求沿着对象链传递,以让处于对象链中的对象得到处理机会。

3,处于对象链中的对象的职责分配。不同的对象完成不同的职责。

4,任务的完成。处于对象链的末尾的对象结束任务并停止消息或请求的继续传递。

优点:

1.责任的分担。每个类只需要处理自己该处理的工作(不该处理的传递给下一个对象完成),明确各类的责任范围,符合类的最小封装原则。

2.可以根据需要自由组合工作流程。如工作流程发生变化,可以通过重新分配对象链便可适应新的工作流程。 3.类与类之间可以以松耦合的形式加以组织。

缺点:

因为处理时以链的形式在对象间传递消息,根据实现方式不同,有可能会影响处理的速度。

迭代模式

介绍:lterator模式也叫迭代模式,是行为模式之一,它把对容器中包含的内部对象的访问委让给外部类,使用Iterator (遍历)按顺序进行遍历访问的设计模式。

在应用Iterator模式之前,首先应该明白Iterator模式用来解决什么问题。或者说,如果不使用Iterator模式,会存在什么问题。。
1.由容器自已实现顺序遍历。直接在容器类里直接添加顺序 遍历方法
2.让调用者自己实现遍历。直接暴露数据细节给
外部。

以上方法1与方法2都可以实现对遍历,这样有问题呢?
1,容器类承担了太多功能:一方面需要提供添
加删除等本身应有的功能;一方面还需要提供遍历访问功能。
2,往往容器在实现遍历的过程中,需要保存遍
历状态,当跟元素的添加删除等功能夹杂在一起,很容易引起混乱和程序运行错误等。

lterator模式就是为了有效地处理按顺序进行遍历访问的一种设计模式,简单地说,Iterator模式提供一 种有效的方法,可以屏蔽聚集对象集合的容器类的实现细节,而能对容器内包含的对象元素按顺序进行有效的遍历访问。

所以,Iterator模 式的应用场景可以归纳为满足以下几个条件:

-访问容器中包含的内部对象

-按顺序访问

相关概念:

Iterator (迭代器接口) :

该接口必须定义实现迭代功能的最小定义方法集比如提供hasNext()和next()方法。

Concretelterator (迭代器实现类) :

迭代器接口Iterator的实现类。可以根据具体情况加以实现。

Aggregate (容器接口) :

定义基本功能以及提供类似Iterator iterator()的方法。

concretelAggregate (容器实现类) :

容器接口的实现类。必须实现Iterator iterator()方法。

优点:

1,实现功能分离,简化容器接口。让容器只实
现本身的基本功能,把迭代功能委让给外部类实现,符合类的设计原则。2,隐藏容器的实现细节。
3,为容器或其子容器提供了一个统-接口,一方面方便调用;另一方面使得调用者不必关注迭代器的实现细节。
4,可以为容器或其子容器实现不同的迭代方法或多个迭代方法。

模板方法模式

介绍:Template Method模式也叫模板方法模式,是行为模式之一,它把具有特定步骤算法中的某些必要的处理委让给抽象方法,通过子类继承对抽象方法的不同实现改变整个算法的行为。

也就是把相关的方法组织在一个模板中,直接调用模板即可,不用再一个一个的调用方法。

应用场景:

Template Method模式- -般应用在具有以下条件的应用中:
-具有统一的操作步骤或操作过程-具有不同的操作细节
-存在多个具有同样操作步骤的应用场景,但某
些具体的操作细节却各不相同

举例:

所谓模板方法模式,其实很简单,可以从模板的角度考虑,就是一个对模板的应用,就好比老师出试卷,每个人的试卷都是一样的,即都是从老师的原版试卷复印来的,这个原版试卷就是一个模板,可每个人写在试卷上的答案都是不一样的,这就是模板方法模式,是不是很好理解。它的主要用途在于将不变的行为从子类搬到超类,去除了子类中的重复代码。

备忘录模式

介绍:Memento模式也叫备忘录模式,是行为模式之它的作用是保存对象的内部状态,并在需要的时候( undo/rollback)恢复对象以前的状态。

相关概念:

Originator (原生者)
需要被保存状态以便恢复的那个对象。

Memento (备忘录)
该对象由Originator创建,主要用来保存Originator的内部状态

Caretaker (管理者)
负责在适当的时间保存/恢复Originator对象的状态

适用场景:

如果一个对象需要保存状态并可通过undo或rollback等操作恢复到以前的状态时,可以使用Memento模式。

1)一个类需要保存它的对象的状态(相当于Originator角色)

2)设计一个类,该类只是用来保存上述对象的状态(相当于Memento角色)

3)需要的时候,Caretaker角 色要求Originator返回一个Memento并加以保存

4) undo或rollback操 作时,通过Caretaker保存 的Memento恢复Originator对象的状态

举例:

备忘录模式大家肯定都见过,比如在玩游戏的时候有一个保存当前闯关的状态的功能,会对当前用户所处的状态进行保存,当用户闯关失败或者需要从快照的地方开始的时候,就能读取当时保存的状态完整地恢复到当时的环境,这一点和VMware上面的快照功能很类似。

与原型模式的区别

原型模式保存的是当前对象的所有状态信息,恢复的时候会生成与保存的对象完全相同的另外一个实例;而备忘录模式保存的是我们关心的在恢复时需要的对象的部分状态信息,相当于快照。

状态模式

介绍:State模式也叫状态模式,是行为设计模式的一种。State模式允许通过改变对象的内部状态而改变对象的行为,这个对象表现得就好像修改了它的类一样。

相关概念:

Context:用户对象
拥有一个State类型的成员,以标识对象的当前状态;
State: 接口或基类
封装与Context的特定状态相关的行为;

ConcreteState:接口实现类或子类
实现了一个与Context某个状态相关的行为。

适用场景:状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转译到表现不同状态的一系列类当中,可以把复杂的判断逻辑简化。

命令模式

介绍:Command模式也叫命令模式,是行为设计模式的一种。Command模式通过被称为
Command的类封装了对目标对象的调用行为以及调用参数。将请求封装为一个对象,从而可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作

相关概念:

Command
Command抽象类。

ConcreteCommand
Command的具体实现类。

Receiver
需要被调用的目标对象。

Invorker
通过Invorker执行Command对象。

适用场景:

在面向对象的程序设计中,一个对象调用另一个对象,一般情况下的调用过程是:创建目标对象实例;设置调用参数;调用目标对象的方法。

但在有 些情况下有必要使用一个专门的类对这种调用过程加以封装,我们把这种专门的类称作command类。一整个调用过程比较繁杂,或者存在多处这种调用。这时,使用Command类对该调用加以封装,便于功能的再利用。

-调用前后需要对调用参数进行某些处理。.

-调用前后需要进行某些额外处理,比如日志,缓存,记录历史操作等。

访问者模式

介绍:Visitor模式也叫访问者模式,是行为模式之一它分离对象的数据和行为,使用Visitor模式,可以不修改已有类的情况下,增加新的操作。将访问操作独立出来变成一个新的类,当我们需要增加访问操作的时候,直接增加新的类,原来的代码不需要任何的改变。

相关概念:

1)访问者角色(Visitor) :

为该对象结构中具体元素角色声明一个访问操作接口。该操作接口的名字和参数标识了发送访问请求给具体访问者的具体元素角色。这样访问者就可以通过该元素角色的特定接口直接访问它。

2)具体访问者角色(Concrete Visitor) :

实现每个由访问者角色(Visitor) 声明的操作。

3)元素角色( Element) :

定义一个Accept操作,它以一一个访问者为参数。

4)具体元素角色(Concrete Element) :

实现由元素角色提供的Accept操作。

5)对象结构角色(Object Structure) :

这是使用访问者模式必备的角色。它要具备以下特征:能枚举它的元素,可以提供一个高层的接口以允许该访问者访问它的元素;可以是一个复合(组合模式)或是一个集合,如一个列表或一个无序集合。

例子:

​ 比如有一个公园,有一到多个不同的组成部分;该公园存在多个访问者:清洁工A负责打扫公园的A部分,清洁工B负责打扫公园的B部分,公园的管理者负责检点各项事务是否完成,.上级领导可以视察公园等等。也就是说,对于同一个公园,不同的访问者有不同的行为操作,而且访问者的种类也可能需要根据时间的推移而变化(行为的扩展性)。

根据软件设计的开闭原则 (对修改关闭,对扩展开放),我们怎么样实现这种需求呢?

附:23中设计模式一一讲解