刘越洋子

真正优秀的人不是比别人强,而是比昨天的自己更优秀!

23种设计模式总结

23种设计模式总结

23种设计模式写了很长时间才全部写完。在这里写下总结以便以后查阅时候方便。

1.创建型

创建型:除了直接new来实例化对象外,提供了多种隐藏创建逻辑的生成对象的方法

1.1 单例模式(Singleton)

意图:保证一个类只有一个实例,并且提供全局的访问点。
特点:
1,私有,静态的类属性(instance)
2,私有的构造方法(保证其他类不能实例化此类)
3,公有,静态的访问实例方法(getInstance)
Singleton

1.2 工厂方法(Factory Method)

意图:定义一个用于创建对象的接口,让子类决定实例化哪一个类。 Factory Method使一个类的实例化延迟到其子类。
特点:
1,被创建对象的类实现共同的接口(程序运行时期动态绑定具体哪个类)
2,工厂:提供创建对象的方法(根据不同的标示,或者提供不同的方法对不同的类进行创建)
3,client:持有工厂或者调用工厂不同的静态方法实现对不同类型的类进行实例化。
工厂方法有三种变形普通工厂,多方法工厂,静态工厂
在以上的三种模式中,第一种如果传入的字符串有误,不能正确创建对象,第三种相对于第二种,不需要实例化工厂类,大多数情况下,我们会选用第三种——静态工厂方法模式。
FactoryMethod

1.3 抽象工厂(Abstract Factory)

意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
特点:
1,一般是拿抽象工厂与工厂方法做为比较。其中工厂方法如果要添加一个被创建的类,必须的修改工厂类。这违背了设计模式中的开闭原则。
2,抽象工厂与工厂方法类似只是对工厂类进行进一步的抽象,让工厂类实现同一个接口。这样如果添加一个新的产品时,需要新建一个实现工厂接口的实现类。
AbstractFactory

1.4 建造模式(Builder)

意图:将一个复杂对象(产品)的构建与它的表示分离(建造者的实现),使得同样的构建过程可以创建不同的表示(建造者接口与具体实现类)。
特点:
1,产品:产品为比较复杂对象。(创建过程繁琐,或者有序。反正是创建过程复杂)
2,建造者:用于创建这个复杂产品和返回这个产品(构建与它的表示分离)
3,导演:负责调用适当的建造者来组建产品,导演类一般不与产品类发生依赖关系,与导演类直接交互的是建造者类。一般来说,导演类被用来封装程序中易变的部分。
Builder

1.5 原型模式(Prototype)

意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。通过new产生一个对象需要非常繁琐的数据准备或访问权限。
特点:
1,实现 Cloneable 接口
2,重写 Object clone 方法
3,深拷贝,浅拷贝 会发生深拷贝的有java中的8中基本类型以及他们的封装类型,另外还有String类型。
其余的都是浅拷贝。(引用类型拷贝是复制指针,其实复制对象和原对象都是指向同一个引用)
Prototype

2.结构型

结构型:通过对象和类的组合,得到新的结构和功能

2.1 适配器模式(Adapter)

意图:将一个类的接口转换成客户希望的另外一个接口。 Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
特点
适配器模式主要用于兼容原系统使用,在不改动原系统类的情况进行适配
类适配器模式:
1.新建目标接口包含原有类的方法和新方法。
2.新建适配类 继承原有类,实现目标接口。
ClassAdapter
对象适配器模式:
1.新建适配类实现目标接口,持有原有类作为属性。定义原有类的方法和新方法。
2.通过适配类的实例,调用原有类方法。
ObjectAdapter
接口适配器模式:用于接口的抽象方法多,而具体只关注某些方法。
1.新建适配类实现 原有接口
2.新建具体类 继承适配类,重写某些方法。
InterfaceAdapter

2.2 装饰器模式(Decorator)

意图:动态地给一个对象添加一些额外的职责。就增加功能来说, decorator模式相比生成子类更为灵活
Decorator

2.3 代理模式(Proxy)

意图:为其他对象提供一种代理以控制对这个对象的访问。
Proxy
特点
1,装饰类和被装饰类(代理类和被代理类)都是实现共同的接口。类图结构大体相同。
2,都是通过装饰类(代理类)访问被装饰的类(被代理的类)。
3,但是两者的注重的方向不一样,装饰器模式突出给原有类增加新功能。而代理类是强调被代理类的访问(保护被代理的对象)。

2.4 门面模式(Facade)

意图:为子系统中的一组接口提供一个一致的界面, Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
特点
1,利用高内聚来降耦合。
2,通过门面角色来控制子系统角色的方法调用
1,子系统角色:Disk,Memory,CPU
2,门面角色:Computer
3,客户端:FacadeTest
Facade

2.5 桥接模式(Bridge)

意图
将抽象部分与它的实现部分分离,使它们都可以独立地变化。
特点
1.把对象的创建与应用分离,交给调用者去根据具体情况创建不同的类。
2.通过桥接类去调用对象的具体方法。
Bridge

2.6 组合模式(Composite)

意图
将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使得用户对单个对象和组合对象的使用具有一致性。
特点
想表示对象的部分-整体层次结构。
希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
通常树形结构的表都会用到组合模式。
Composite

2.7 享元模式(FLYWEIGHT)

意图
运用共享技术有效地支持大量细粒度的对象。
特点
抽象享元角色:为具体享元角色规定了必须实现的方法,而外蕴状态就是以参数的形式通过此方法传入。在Java中可以由抽象类、接口来担当。
具体享元角色:实现抽象角色规定的方法。如果存在内蕴状态,就负责为内蕴状态提供存储空间。
享元工厂角色:负责创建和管理享元角色。要想达到共享的目的,这个角色的实现是关键!
客户端角色:维护对所有享元对象的引用,而且还需要存储对应的外蕴状态。
Flyweight

3.行为型

行为型:解决对象之间的通行和功能职责分配

3.1 责任链模式(chain of responsibility)

意图
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这
些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
特点
Hander 抽象处理者 具有抽象的处理方法
ConcreteHander 具体处理者 实现Hander 并且实现处理方法
将所有的处理者连成一个链 从上到下向下调用,直到处理完毕或者无法处理返回.
chainofresponsibility

3.2命令模式(Command)

意图
将一个请求封装为一个对象,从而使你可用不同的请求对客户端进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
例: 老板让员工刷碗,扫地等,如果用命令模式 老板类不需要关心哪个员工去干活,而是关心命令,老板只要发布命令,命令执行就可以了.
特点
Command:定义命令的接口,声明执行的方法。
ConcreteCommand:命令接口实现对象;通常会持有接受者,并调用接受者的功能来完成命令要执行的操作。
Receiver:接受者,真正执行命令的对象。任何类都可以成为一个接受者,只要它能够实现命令要求实现的相应功能。
Invoker:命令发起者 ,通常会持有命令对象。可以持有很多命令对象。
Command

3.3 解释器模式(Interpreter)

意图
给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子.
如果一种特定类型的问题发生的频率足够高 , 那么可能就值得将该问题的各个实例表述为一个简单语言中的句子。这样就可以构建一个解释器 , 该解释器通过解释这些句子来解决该问题。
特点
Expression:抽象表达式,声明一个所有的具体表达式都需要实现的抽象接口;这个接口主要是一个interpret()方法,称做解释操作。
Terminal Expression:终结符表达式,实现了抽象表达式所要求的接口;文法中的每一个终结符都有一个具体终结表达式与之相对应。比如公式R=R1+R2,R1和R2就是终结符,对应的解析R1和R2的解释器就是终结符表达式。
Nonterminal Expression:非终结符表达式,文法中的每一条规则都需要一个具体的非终结符表达式,非终结符表达式一般是文法中的运算符或者其他关键字,比如公式R=R1+R2中,“+”就是非终结符,解析“+”的解释器就是一个非终结符表达式。
Context:环境,它的任务一般是用来存放文法中各个终结符所对应的具体值,比如R=R1+R2,给R1赋值100,给R2赋值200,这些信息需要存放到环境中。
Client: 构建(或被给定 ) 表示该文法定义的语言中一个特定的句子的抽象语法树。该抽象语法树由Nonterminal Expression和Terminal Expression 的实例装配而成。调用解释操作。
Interpreter

3.4 迭代器模式(Iterator)

意图
提供一种方法顺序访问一个聚合对象中各个元素 , 而又不需暴露该对象的内部表示。
针对不同的需要,可能要以不同的方式遍历这个列表。但是即使可以预见到所需的那些遍历操作,你可能也不希望列表的接口中充斥着各种不同遍历的操作。有时还可能需要在同一个表列上同时进行多个遍历。
迭代器模式可用来:
• 访问一个聚合对象的内容而无需暴露它的内部表示。
• 支持对聚合对象的多种遍历。
• 为遍历不同的聚合结构提供一个统一的接口 (即, 支持多态迭代)。
特点
ConcreteAggregate: 具体聚集
实现Iterable接口, 返回ConcreteIterator的一个适当的实例;
ConcreteIterator : 具体迭代器
实现Iterator接口(最好作为具体聚集的内部类), 对该聚集遍历时跟踪当前位置.
Iterator

3.5 中介者模式(Mediator)

意图
用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
在下列情况下使用中介者模式 :
• 一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结构混乱且难以理解。
• 一个对象引用其他很多对象并且直接与这些对象通信 ,导致难以复用该对象。
• 想定制一个分布在多个类中的行为,而又不想生成太多的子类。
特点
• Mediator(中介者 )
— 中介者定义一个接口用于与各同事(Colleague)对象通信。
• ConcreteMediator(具体中介者)
— 具体中介者通过协调各同事对象实现协作行为。
— 了解并维护它的各个同事。
• Colleague class(同事类)
— 每一个同事类都知道它的中介者对象。
— 每一个同事对象在需与其他的同事通信的时候,与它的中介者通信。
同事向一个中介者对象发送和接收请求。中介者在各同事间适当地转发请求以实现协作行为。
Mediator

3.6 观察者模式(Observer)

意图
定义对象间的一种一对多的依赖关系 ,当一个对象的状态发生改变时 , 所有依赖于它的对象都得到通知并被自动更新。
将一个系统分割成一系列相互协作的类有一个常见的副作用:需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,因为这样降低了它们的可重用性。
在以下任一情况下可以使用观察者模式 :
• 当一个抽象模型有两个方面 , 其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
• 当对一个对象的改变需要同时改变其它对象 , 而不知道具体有多少对象有待改变。
• 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之 , 你不希望这些对象是紧密耦合的。
特点
• Subject(目标)
— 目标知道它的观察者。可以有任意多个观察者观察同一个目标。
— 提供注册和删除观察者对象的接口。
• Observer(观察者)
— 为那些在目标发生改变时需获得通知的对象定义一个更新接口。
• ConcreteSubject(具体目标)
— 将有关状态存入各 ConcreterObserver对象。
— 当它的状态发生改变时 , 向它的各个观察者发出通知。
• ConcreterObserver(具体观察者)
— 维护一个指向ConcreteSubject对象的引用。
— 存储有关状态,这些状态应与目标的状态保持一致。
— 实现Observer的更新接口以使自身状态与目标的状态保持一致。
• 当ConcreteSubject发生任何可能导致其观察者与其本身状态不一致的改变时,它将通知它的各个观察者。
• 在得到一个具体目标的改变通知后 , ConcreteObserver 对象可向目标对象查询信息。ConcreteObserver使用这些信息以使它的状态与目标对象的状态一致。
Observer

3.7 备忘录模式(Memento)

意图
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
有时有必要记录一个对象的内部状态。为了允许用户取消不确定的操作或从错误中恢复过来,需要实现检查点和取消机制 , 而要实现这些机制,你必须事先将状态信息保存在某处,这样才能将对象恢复到它们先前的状态。
在以下情况下使用备忘录模式:
• 必须保存一个对象在某一个时刻的 (部分)状态, 这样以后需要时它才能恢复到先前的状态。
• 如果一个用接口来让其它对象直接得到这些状态,将会暴露对象的实现细节并破坏对象的封装性。
特点
• Memento(备忘录)
— 备忘录存储原发器对象的内部状态。原发器根据需要决定备忘录存储原发器的哪些内部状态。
— 防止原发器以外的其他对象访问备忘录。备忘录实际上有两个接口,
管理者( Caretaker)只能看到备忘录的窄接口 — 它只能将备忘录传递给其他对象。
原发器能够看到一个宽接口, 允许它访问返回到先前状态所需的所有数据。理想的情况是只允许生成本备忘录的那个原发器访问本备忘录的内部状态。
• Originator(原发器)
— 原发器创建一个备忘录 ,用以记录当前时刻它的内部状态。
— 使用备忘录恢复内部状态 .。
• Caretaker(负责人)
— 负责保存好备忘录。
— 不能对备忘录的内容进行操作或检查。
• 管理器向原发器请求一个备忘录 , 保留一段时间后 ,将其送回给原发器 ,有时管理者不会将备忘录返回给原发器 , 因为原发器可能根本不需要退到先前的状态。
• 备忘录是被动的。只有创建备忘录的原发器会对它的状态进行赋值和检索。
Memento

3.8 状态模式(State)

意图
允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。
在下面的两种情况下均可使用 State模式:
• 一个对象的行为取决于它的状态 , 并且它必须在运行时刻根据状态改变它的行为。
• 一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。这个状态通常用一个或多个枚举常量表示。通常 , 有多个操作包含这一相同的条件结构。 State模式将每一个条件分支放入一个独立的类中。这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。
特点
• Context(环境)
— 定义客户感兴趣的接口。
— 维护一个ConcreteState子类的实例,这个实例定义当前状态。
• State(状态 )
— 定义一个接口以封装与 Context的一个特定状态相关的行为。
• ConcreteState subclasses(具体状态子类)
— 每一子类实现一个与 Context的一个状态相关的行为。
• Context将与状态相关的请求委托给当前的 ConcreteState对象处理。
• Context可将自身作为一个参数传递给处理该请求的状态对象。这使得状态对象在必要时可访问Context。
• Context是客户使用的主要接口。客户可用状态对象来配置一个Context,一旦一个Context配置完毕 , 它的客户不再需要直接与状态对象打交道。
• Context或ConcreteState子类都可决定哪个状态是另外哪一个的后继者,以及是在何种条件下进行状态转换。
State

3.9 策略模式(Strategy)

意图
定义一系列的算法 ,把它们一个个封装起来 , 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
当存在以下情况时使用 Strategy模式
• 许多相关的类仅仅是行为有异。“策略”提供了一种用多个行为中的一个行为来配置一个类的方法。
• 需要使用一个算法的不同变体。例如,你可能会定义一些反映不同的空间 /时间权衡的算法。当这些变体实现为一个算法的类层次时 ,可以使用策略模式。
• 算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构。
• 一个类定义了多种行为 , 并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的 Strategy类中以代替这些条件语句。
特点
• Strategy(策略 )
— 定义所有支持的算法的公共接口。 Context使用这个接口来调用某 ConcreteStrategy定义的算法。
• ConcreteStrategy(具体策略)
— 以Strategy接口实现某具体算法。
• Context(上下文)
— 用一个ConcreteStrategy对象来配置。
— 维护一个对 Strategy对象的引用。
— 可定义一个接口来让 Strategy访问它的数据。
Strategy

3.10 模板方法模式(TemplateMethod)

意图
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。 TemplateMethod使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
模板方法应用于下列情况:
• 一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
• 各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。首先识别现有代码中的不同之处,并且将不同之处分离为新的操作。最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。
• 控制子类扩展。模板方法只在特定点调用操作,这样就只允许在这些点进行扩展。
特点
• AbstractClass(抽象类)
— 定义抽象的 原语操作( primitive operation) ,具体的子类将重定义它们以实现一个算法的各步骤。
— 实现一个模板方法 ,定义一个算法的骨架。该模板方法不仅调用原语操作,也调用定义在AbstractClass或其他对象中的操作。
• ConcreteClass(具体类)
— 实现原语操作以完成算法中与特定子类相关的步骤。
ConcreteClass靠AbstractClass来实现算法中不变的步骤。
TemplateMethod

3.11 访问者模式(Visitor)

意图
表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
在下列情况下使用 Visitor模式:
• 一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依赖于其具体类的操作。
• 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而你想避免让这些操作“污染”这些对象的类。 Visitor使得你可以将相关的操作集中起来定义在一个类中。当该对象结构被很多应用共享时,用 Visitor模式让每个应用仅包含需要用到的操作。
• 定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。改变对象结构类需要重定义对所有访问者的接口,这可能需要很大的代价。如果对象结构类经常改变,那么可能还是在这些类中定义这些操作较好。
特点
• Vi s i t o r(访问者)
— 为该对象结构中 ConcreteElement的每一个类声明一个 Visit操作。该操作的名字和特征标识了发送 Vi s i t请求给该访问者的那个类。这使得访问者可以确定正被访问元素的具体的类。这样访问者就可以通过该元素的特定接口直接访问它。
• ConcreteVisitor(具体访问者)
— 实现每个由 Visitor声明的操作。每个操作实现本算法的一部分,而该算法片断乃是对应于结构中对象的类。ConcreteVisitor为该算法提供了上下文并存储它的局部状态。这一状态常常在遍历该结构的过程中累积结果。
• Element(元素)
— 定义一个Accept操作,它以一个访问者为参数。
• ConcreteElement(具体元素)
— 实现Accept操作,该操作以一个访问者为参数。
• ObjectStructure(对象结构)
— 能枚举它的元素。
— 可以提供一个高层的接口以允许该访问者访问它的元素。
— 可以是一个复合或是一个集合,如一个列表或一个无序集 合。
Visitor

阅读更多
版权声明:本文为博主原创文章,允许转载,请加原文链接。 https://blog.csdn.net/oYueYang1/article/details/79974536
文章标签: 设计模式
个人分类: 设计模式
上一篇linux mint18 字体设置(微软雅黑)
下一篇Java并发编程一 多线程
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭