设计模式学习笔记

        此篇博客主要总结设计模式的一些定义和特点。在最后有设计模式的总结分类,涉及到大量java的相关知识,有部分javaweb的知识。其它涉及swift语言只有一句但不影响理解。对编译、系统有基础当然是更好

1:命令模式

定义:将一个请求封装为一个对象,从而使用户可用不同的请求进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。(Encapsulate a request as an object,thereby letting you parameterize clients with different requests,queue or log request,and support undoable operations)。

解释:命令模式是关于怎样处理一个对象请求另一个对象调用其方法完成某项任务的一种模式。举例来说A要B做一件事C,那么把C封装为一个命令,A调用C,B再接受C,使得C开始。这样AB就不直接接触,实现松耦合。无论是增加调用者A,还是接受者C都比较方便。这样还有一个好处,就是命令的顺序执行方便记录日志,当然也就能比较好的支持撤销操作(比如回滚)。

使用情景:程序需要在不同时刻指定、排列和执行请求;程序需要提供撤销操作;程序支持宏操作。


2:观察者模式

定义:定义对象间的一对多依赖关系,当一个对象的状态发生变化时,所有的依赖的对象都得到通知并自动更新。(Define a one-to-many between objects so that when one object changes,state,all its dependents are notified and updated automatically)。

解释:参照“求职中心“”-求职者”模型,中心是A对象,求职者是B对象并且依赖A对象的信息数据。当A变化时,B要知晓其中的变化。这就是1:n的观察者模型。在观察者模式中,有“推”“拉”数据两种方式,显然推送属于“推”,观察者调用方法去取得数据属于“拉”。

使用情景:一个对象的数据更新时需要通知其它对象而他们之间不要形成紧耦合;一个对象数据更新,这个对象需要让其它对象也更新相应数据但这个对象不知道具体多少对象要更新数据。


3:装饰模式

定义:动态的给对象添加一些额外的职责。就功能来说装饰模式相比生成子类更加灵活。(Attach additional responsibilities to an object dynamically.Decorators provied a flexible alternative to subclassing for extends functionality).

解释:如定义说的那样。比如定义了一个猫类喝水的对象,实例化得到对象Tom对象,简称T对象,T对象还会抓老鼠(也许是叫jerty的老鼠==)那么实例化后的对象T要装饰一下:添加抓老鼠的方法。这个就叫做:装饰。在举一个例子,一只bird的类,实现了飞100米功能,现在要飞150米,就加一个飞50米功能。先飞100,在飞50。在这个模式里面有四种角色 

抽象组件:是抽象类,定义了”被装饰者“要进行”装饰的方法。

具体组件:抽象组件子类,”被装饰者““。

装饰:也是一个抽象组件的子类,弹装饰还包含一个抽象组件声明的变量以保存”被装饰者“的引用。

具体装饰:是装饰的一种非抽象子类,具体装饰的实例成为”装饰者“。

使用情景:程序想动态增强类的某个对象的功能,又不影响到该类其它对象;采用继承来增强对象功能不利于系统维护和扩展。

4:策略模式:定义一系列算法,把它们一个个封装起来并且使它们可以相互替换。本模式使得算法可独立于使用它的客户而变化。(Define a family of algorithms,encapsulate each one ,and make them interchangeable.Strategy let the algorithm vary independently from clients the use it )。

解释:连长有一个让士兵排队的权利:lineUp()方法表示。但是每个连长的排队规则不一样,那么,设计一个抽象的策略类。每个连长实现这个抽象类的lineUp方法,实现自己的策略。可以看出“面向抽象编程”跟这个息息相关。

应用情景:一个类有多个行为,且这些行为在这个类的方法中以多个条件语句形式出现,可以使用策略模型避免大量条件语句。(用多个类代替语句貌似也不怎么好啊);程序不需要暴露复杂的与算法相关的数据结构;需要一个算法的不同变体。


5:适配器模式

定义:将一个类的接口转换成客户希望的另外的一个接口。Adapter模式使得原来由于接口不兼容而不能一起工作的那些泪可以一起工作。(不放英文了)

解释:字面理解就可以。比如电源适配器,就是将不能直接使用的电转化为特定电器可以使用的。

应用情景:一个程序想使用已经存在的类,但该类所实现的接口和当前接口不一致。


6:责任链模式

定义:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链处理请求,知道有一个对象处理请求为止。

解释:参照定义。责任链模式是使用多个对象处理用户请求的成熟模式。

应用情景:有多个对象处理用户请求,希望在程序运行期间对象自动处理;用户不必明确接受者,向多个对象发送请求;程序希望动态定制可处理用户请求的对象集合(写到这大家是不是感觉Sping的拦截就是这种?)


7:外观模式

定义:为系统中的一组接口提供一个已知的界面,Facade模式定义了一个高层的接口,这个接口使得这一子系统更加容易使用。

解释:比如有三个邮寄包裹的子系统:Check、Weight、Transport,创造一个ServerForClient的类,这个类包含那三个子系统,那么用户就可以直接用ServerForClient类而不必了解三个子系统。

应用情景:对于复杂系统,需要为用户提供一个简单的交互操作;不希望客户和子系统中的类有耦合,这样提高了子系统的独立性和可移植性;整个系统是层次结构,不希望子系统有太多的直接交互。

8:迭代器模式

定义:提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。

解释:迭代器模式是对遍历集合的成熟模式,迭代器模式的关键是将遍历集合的任务交给一个迭代器对象。比如常见的java常见的next()方法。

应用场景:遍历集合不知道内部如何存储或者多个迭代器遍历一个集合。(其实就是遍历集合==)


9:中介者模式

定义:用一个中介对象来封装一系列的对象交互。中介者使得对象不需要显示的相互引用,从而使其耦合松散,而且可以独立的改变它们之间的交互。

解释:这是封装一系列成熟对象交互的成熟模式。让我们想想数据库的多对多模型,中间表就是一个中介。或者想想Spring里面的配置文件,显然也是一个中介,把所有的bean声明在配置文件中集中管理。

应用场景:许多对象以复杂的方式交互,所导致的依赖关系使得系统难以维护和理解;一个对象应用其他很多对象,导致难以复用该对象。


10:工厂方法模式

定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Metthod使得一个类的实例化延迟到其子类。

解释:工厂方法简直在hibernate和mybatis里面出现太多次,然而以前都是不理解的==。举例来说:

抽象产品PenCore.class

public abstract class PenCore{

String color;

public abstract void writeWord(String s);

}


接下来是三个具体产品

RedPenCore.class

public class RedPenCore extends PenCore{

RedPenCore(){

color = "红色";

}

}

同理有BluePenCore.class,BlackPenCore.class


接下来是构造者BallPen,class

public abstract class BallPen{

BallPen(){

System.out.println("生产了一只装有"+getPenCore.color()+"的笔");

}

public abstract  getPenCore();//工厂方法

}


接下来是具体的构造者

RedBallPen.class

public class RedBallPen extends BallPen{

public PenCore getPenCore(){

return new RedPenCore();

}

}

同理可以有BlueBallPen.class等。

使用情景:用户需要一个类的子类的实例但不希望与该类的子类形成耦合;用户需要一个类的子类,但用户不知道该类有哪些子类可用。


11:抽象工厂模式

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

解释:关键在于在一个抽象类或接口中定义若干个抽象方法,这些抽象方法分别返回某个类的实例,该抽象类或接口让其子类或实现该接口的类重写这些抽象方法为用户提供一系列先关的对象。使用抽象工厂模式可以为用户创建一系列相关的对象使得用户和创建这些对象的类脱耦。

应用情景:系统为用户提供多个相关对象,但不希望用户直接使用new运算符实例化这些对象,即脱耦;系统为用户提供多个相关对象以便用户联合使用它们,但不希望用户决定对象的关联;系统需要为用户提供多个对象,用户只要知道哪些方法可用而不关心对象的创建过程。


12:生成器模式

定义:将一个复杂对象的构建与它的表示分离,使同样的构建过程可以创建不同的表示。

解释:所看的书中有一个例子,有一个抽象生成器类,定义了得到Button,Label和文本的方法以及一个getPanel()方法,然后具体的生成器实现抽象生成器的方法,在getPanel方法中,两个具体的生成器对添加三个组件(Button,Label,TextField)的顺序不同从而实现了得到不同Panel的方法。指挥者类就可以调用想要的生成器得到想要的Panel。

应用情景:系统为用户提供一个内部结构复杂的对象,而且在构造方法中编写创建该对象的代码无法满足用户需求时就可以使用生成器模式构造对象;当某些系统要求对象的构造过程独立于创建该对象的时候。


13:原型模式

定义:用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。

解释:在java中实现Cloneable接口可以实现这种模型,或者Serializable接口也可以实现。简单来说就是复制对象本身,如果不想调用构造方法构造实例,而是想通过已经有的实例得到实例,那么在实例中实现clone可以得到复制的对象。当创造类的新实例的代价太大时,通过原型模型复制一个可以提高效率。

应用情景:程序需要从一个对象出发得到若干和其状态相同并可独立变化状态的对象时;当对象的创建需要独立于它的构造过程和表示时;一个类创建实例状态不是很多那么就可以将这个类的一个实例定义为原型,那么通过复制该原型得到新的实例可能比重新使用类的构造方法更方便。


14:单件模式

定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

解释:意思很好理解,参照定义。在java中,关键在于将构造方法设置为private权限,并且返回它的唯一实例的类方法(static)。单件类的唯一实例由单件类本身控制,所以可以很好控制用户何时访问它。

应用情景:系统只需要某个类只能有一个实例。


15:组合模式

定义:将对象组合成树形结构以表示“部分”-“整体”的层次结构。Composite使用户对单个对象和组合对象的使用有一致性。

解释:如果一个对象包含对另一个对象的引用,称这样的对象为组合对象。在这种模式中,组合对象和个体对象实现了相同的接口。

应用情景:当想表示对象的部分-整体层次结构;希望用户用一直的方式处理个体对象和组合对象。


16:桥接模式

定义:将抽象部分与它的事项部分分离,使它们可以独立的变化。

解释:顾名思义,抽象类和实现类放在两个不同的类层次中,从而可以独立改变。A抽象类,B是子类,C是实现类,在抽象类中引入C对象,则B作为桥接类,可以调用C实现功能。

应用情景:不想让抽象和某些重要的实现代码是固定的绑定管理,这部分实现可运行时动态决定;抽象和实现着都可以集成的方法独立的扩充互不影响;希望对实现者层次代码的修改对抽象层不产生影响,即抽象层的代码不必重新编译。


17:状态模式

定义:允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。

解释:一个对象的状态依赖于它的变量的取值情况,对象在不同的运行环境中可能具有不同的状态。状态模式的关键是将对象的状态封装成为独立的类,对象调用方法时,可以委托当前对象所具有的状态调用相应的方法,使当前对象看起来好像修改了它的类。在状态模式中,每一个状态是一个类,方便添加新的状态。

应用情景:一个对象的行为依赖于它的状态,它必须在运行时根据状态改变行为;需要编写大量的条件分支语句来决定一个操作的行为,而且这些条件恰好表示对象的一种状态。


18:模板方法模式

定义:定义一个操作中算法的骨架,而将一些步骤延迟到子类中。模板方法使子类可以不改变一个算法的结构即可定义该算法的某些特定的步骤。

解释:比如velocity模板,就是定义一个通用模板然后调用。在模板方法模式中注意“抽象模板”和“具体模板”两个名词。抽象模板定义了操作方法(算法骨架),具体模板实现了特定的步骤,可以通过使用模板来实现不同的算法。

应用情景:设计者要给出算法的固定步骤但是步骤的具体实现交给子类;在抽象模板模式中,可以通过钩子方法对某些步骤进行挂钩,具体模板通过钩子可以选择算法骨架中的某些步骤。(钩子方法是抽象模板中定义的具体方法,但给出空实现或默认的实现,并允许子类重写这个具体方法)


19:代理模式

定义:为其他对象提供一种代理以控制对这个对象的访问。

解释:当用户希望与某个对象打交道但是程序不希望用户直接访问该对象,而是提供一个特殊的代理对象,让用户通过代理对象访问最终对象。在swift语言中就有delegate相关的类。在代理模式中,被代理对象和代理对象共有相同的接口。参照生活中代理人的角色也可以认识到代理模式的意义。在个人看来,实际实现过程类似于:用户请求对象B,但实际要通过代理对象A的这一关,经过A的处理,然后A觉得可以,在方法中调用B。

应用情景:程序可能不希望用户直接访问对象而是提供一个特殊的对象以控制对当前对象的访问;一个对象需要很长的时间才能加载完成;对象位于远程主机上,需要为用户提供访问该远程对象的能力。


20:享元模式

定义:运用共享技术有效的支持大量细粒度的对象。

解释:所谓享元模式,就是抽出一部分可以共享的数据结构。享元模式的关键是使用一个称为享元的对象为其他对象提供共享的状态,而且能够保证使用享元的对象不能更改享元中的数据。

应用情景:一个应用程序使用大量的对象,这些对象之间部分属性本质上相同,这时候可以用享元封装相同的部分;对象的多数状态都可以变为外部状态(享元维护的数据称为内部状态,对应其他为外部状态),就可以将这些对象作为系统中的享元来使用。


21:访问者模式

定义:表示一个作用于某对象结构中的各个元素的操作。它可以在不改变各个元素的类的前提下定义作用于这些元素的新操作。

解释:顾名思义,访问者模式就是让一个称为访问者的对象访问对象。简单举例来说就是对一个实例有多个方法,让另外一个对象B作为访问者去调用实例的方法。所以在这个实例中可以方便添加新方法。

应用情景:一个对象结构,包含很多对象,想对这个对象集合中添加新的操作;需要对集合中的对象进行很多不同并且不相关的操作,而又不想修改对象的类,就可以使用访问者模式。


22:备忘录模式

定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可将该对象恢复到原先保存的状态。

解释:从定义就可以理解含义了,区分原型模式,原型模式是为了得到实例,而备忘录模式是为了保存实例。

应用情景:必须保存一个对象在某一时刻的全部或部分状态,以便在需要时回复该对象先前的状态;一个对象不想提供public权限,诸如getXXX()的方法让其它对象得到自己的内部状态。


23:解释器模式

定义:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

解释:个人理解,编译中可能要学习,实际中可能用的不多。

应用情景:简单的语言需要解释执行,并且可以将语言的每一个规则表示为一个类时,就可以用解释器模式。


模式分类总结

模式总共分为三大类:创建型模式、行为型模式、结构型模式

创建型模式特点:涉及对象的实例化,不让用户代码依赖于对象的创建或排列方式,避免用户直接使用new运算符创建对象

创建型模式包括:工厂方法模式、抽象工厂模式、生成器模式、原型模式、单件模式

行为型模式特点:涉及怎样合理的设计对象之间的交互通信,以及怎样合理的为对象分配职责,让设计富有弹性,易维护,易复用

行为型模式包括:责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式、访问者模式共11种

结构型模式特点:涉及如何组合类和对象以形成更大的结构,和类有关的结构型模式设计如何合理的利用继承机智;和对象有关的结构型模式涉及如何合理的使用对象组合机制

结构型模式包括:适配器模式、组合模式、代理模式、享元模式、桥接模式、装饰模式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值