23种设计模式全解析

1、什么是设计模式                                                                                                  html

设计模式(Design pattern)是一套被反复使用、多数人知晓的、通过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石同样。项目中合理的运用设计模式能够完美的解决不少问题,每种模式在如今中都有相应的原理来与之对应,每个模式描述了一个在咱们周围不断重复发生的问题,以及该问题的核心解决方案,这也是它能被普遍应用的缘由。简单说:java

模式:在某些场景下,针对某类问题的某种通用的解决方案。算法

场景:项目所在的环境编程

问题:约束条件,项目目标等设计模式

解决方案:通用、可复用的设计,解决约束达到目标。数据结构

2、设计模式的三个分类                                                                                            架构

建立型模式:对象实例化的模式,建立型模式用于解耦对象的实例化过程。asp.net

结构型模式:把类或对象结合在一块儿造成一个更大的结构。函数

行为型模式:类和对象如何交互,及划分责任和算法。工具

以下图所示:

3、各分类中模式的关键点                                                                                       

单例模式:某个类只能有一个实例,提供一个全局的访问点。

简单工厂:一个工厂类根据传入的参量决定建立出那一种产品类的实例。

工厂方法:定义一个建立对象的接口,让子类决定实例化那个类。

抽象工厂:建立相关或依赖对象的家族,而无需明确指定具体类。

建造者模式:封装一个复杂对象的构建过程,并能够按步骤构造。

原型模式:经过复制现有的实例来建立新的实例。

 

适配器模式:将一个类的方法接口转换成客户但愿的另一个接口。

组合模式:将对象组合成树形结构以表示“”部分-总体“”的层次结构。

装饰模式:动态的给对象添加新的功能。

代理模式:为其余对象提供一个代理以便控制这个对象的访问。

亨元(蝇量)模式:经过共享技术来有效的支持大量细粒度的对象。

外观模式:对外提供一个统一的方法,来访问子系统中的一群接口。

桥接模式:将抽象部分和它的实现部分分离,使它们均可以独立的变化。

 

模板模式:定义一个算法结构,而将一些步骤延迟到子类实现。

解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器。

策略模式:定义一系列算法,把他们封装起来,而且使它们能够相互替换。

状态模式:容许一个对象在其对象内部状态改变时改变它的行为。

观察者模式:对象间的一对多的依赖关系。

备忘录模式:在不破坏封装的前提下,保持对象的内部状态。

中介者模式:用一个中介对象来封装一系列的对象交互。

命令模式:将命令请求封装为一个对象,使得能够用不一样的请求来进行参数化。

访问者模式:在不改变数据结构的前提下,增长做用于一组对象元素的新功能。

责任链模式:将请求的发送者和接收者解耦,使的多个对象都有处理这个请求的机会。

迭代器模式:一种遍历访问聚合对象中各个元素的方法,不暴露该对象的内部结构。

 

4、概说23种设计模式                                                                                       

1.单例模式                                                                                                  

单例模式,它的定义就是确保某一个类只有一个实例,而且提供一个全局访问点。

单例模式具有典型的3个特色:一、只有一个实例。 二、自我实例化。 三、提供全局访问点。

 所以当系统中只须要一个实例对象或者系统中只容许一个公共访问点,除了这个公共访问点外,不能经过其余访问点访问该实例时,可使用单例模式。

单例模式的主要优势就是节约系统资源、提升了系统效率,同时也可以严格控制客户对它的访问。也许就是由于系统中只有一个实例,这样就致使了单例类的职责太重,违背了“单一职责原则”,同时也没有抽象类,因此扩展起来有必定的困难。其UML结构图很是简单,就只有一个类,以下图:

 

2.工厂方法模式                                                                                        

做为抽象工厂模式的孪生兄弟,工厂方法模式定义了一个建立对象的接口,但由子类决定要实例化的类是哪个,也就是说工厂方法模式让实例化推迟到子类。

工厂方法模式很是符合“开闭原则”,当须要增长一个新的产品时,咱们只须要增长一个具体的产品类和与之对应的具体工厂便可,无须修改原有系统。同时在工厂方法模式中用户只须要知道生产产品的具体工厂便可,无须关系产品的建立过程,甚至连具体的产品类名称都不须要知道。虽然他很好的符合了“开闭原则”,可是因为每新增一个新产品时就须要增长两个类,这样势必会致使系统的复杂度增长。其UML结构图:

 

3.抽象工厂模式                                                                                 

所谓抽象工厂模式就是提供一个接口,用于建立相关或者依赖对象的家族,而不须要明确指定具体类。他容许客户端使用抽象的接口来建立一组相关的产品,而不须要关系实际产出的具体产品是什么。这样一来,客户就能够从具体的产品中被解耦。它的优势是隔离了具体类的生成,使得客户端不须要知道什么被建立了,而缺点就在于新增新的行为会比较麻烦,由于当添加一个新的产品对象时,须要更加须要更改接口及其下全部子类。其UML结构图以下:

 

 

4.建造者模式                                                                                  

对于建造者模式而已,它主要是将一个复杂对象的构建与表示分离,使得一样的构建过程能够建立不一样的表示。适用于那些产品对象的内部结构比较复杂。

建造者模式将复杂产品的构建过程封装分解在不一样的方法中,使得建立过程很是清晰,可以让咱们更加精确的控制复杂产品对象的建立过程,同时它隔离了复杂产品对象的建立和使用,使得相同的建立过程可以建立不一样的产品。可是若是某个产品的内部结构过于复杂,将会致使整个系统变得很是庞大,不利于控制,同时若几个产品之间存在较大的差别,则不适用建造者模式,毕竟这个世界上存在相同点大的两个产品并非不少,因此它的使用范围有限。其UML结构图:

 

 

5.原型模式                                                                                      

在咱们应用程序可能有某些对象的结构比较复杂,可是咱们又须要频繁的使用它们,若是这个时候咱们来不断的新建这个对象势必会大大损耗系统内存的,这个时候咱们须要使用原型模式来对这个结构复杂又要频繁使用的对象进行克隆。因此原型模式就是用原型实例指定建立对象的种类,而且经过复制这些原型建立新的对象。

它主要应用与那些建立新对象的成本过大时。它的主要优势就是简化了新对象的建立过程,提升了效率,同时原型模式提供了简化的建立结构。UML结构图:

 

模式结构
原型模式包含以下角色:
Prototype:抽象原型类
ConcretePrototype:具体原型类
Client:客户类

6.适配器模式                                                                                

在咱们的应用程序中咱们可能须要将两个不一样接口的类来进行通讯,在不修改这两个的前提下咱们可能会须要某个中间件来完成这个衔接的过程。这个中间件就是适配器。所谓适配器模式就是将一个类的接口,转换成客户指望的另外一个接口。它可让本来两个不兼容的接口可以无缝完成对接。

做为中间件的适配器将目标类和适配者解耦,增长了类的透明性和可复用性。

 

适配器模式包含以下角色:
Target:目标抽象类
Adapter:适配器类
Adaptee:适配者类
Client:客户类

7.桥接模式                                                                                   

若是说某个系统可以从多个角度来进行分类,且每一种分类均可能会变化,那么咱们须要作的就是讲这多个角度分离出来,使得他们能独立变化,减小他们之间的耦合,这个分离过程就使用了桥接模式。所谓桥接模式就是讲抽象部分和实现部分隔离开来,使得他们可以独立变化。

桥接模式将继承关系转化成关联关系,封装了变化,完成了解耦,减小了系统中类的数量,也减小了代码量。

桥接模式包含以下角色:
Abstraction:抽象类
RefinedAbstraction:扩充抽象类
Implementor:实现类接口
ConcreteImplementor:具体实现类

 

8.组合模式                                                                                       

组合模式组合多个对象造成树形结构以表示“总体-部分”的结构层次。它定义了如何将容器对象和叶子对象进行递归组合,使得客户在使用的过程当中无须进行区分,能够对他们进行一致的处理。在使用组合模式中须要注意一点也是组合模式最关键的地方:叶子对象和组合对象实现相同的接口。这就是组合模式可以将叶子节点和对象节点进行一致处理的缘由。

虽然组合模式可以清晰地定义分层次的复杂对象,也使得增长新构件也更容易,可是这样就致使了系统的设计变得更加抽象,若是系统的业务规则比较复杂的话,使用组合模式就有必定的挑战了。

 

 模式结构
组合模式包含以下角色:
Component: 抽象构件
Leaf: 叶子构件
Composite: 容器构件
Client: 客户类

9.装饰模式                                                                                         

咱们能够经过继承和组合的方式来给一个对象添加行为,虽然使用继承可以很好拥有父类的行为,可是它存在几个缺陷:1、对象之间的关系复杂的话,系统变得复杂不利于维护。2、容易产生“类爆炸”现象。3、是静态的。在这里咱们能够经过使用装饰者模式来解决这个问题。

装饰者模式,动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更加有弹性的替代方案。虽然装饰者模式可以动态将责任附加到对象上,可是他会产生许多的细小对象,增长了系统的复杂度。

模式结构
装饰模式包含以下角色:
Component: 抽象构件
ConcreteComponent: 具体构件
Decorator: 抽象装饰类
ConcreteDecorator: 具体装饰类

 

10.外观模式                                                                                            

咱们都知道类与类之间的耦合越低,那么可复用性就越好,若是两个类没必要彼此通讯,那么就不要让这两个类发生直接的相互关系,若是须要调用里面的方法,能够经过第三者来转发调用。外观模式很是好的诠释了这段话。外观模式提供了一个统一的接口,用来访问子系统中的一群接口。它让一个应用程序中子系统间的相互依赖关系减小到了最少,它给子系统提供了一个简单、单一的屏障,客户经过这个屏障来与子系统进行通讯。经过使用外观模式,使得客户对子系统的引用变得简单了,实现了客户与子系统之间的松耦合。可是它违背了“开闭原则”,由于增长新的子系统可能须要修改外观类或客户端的源代码。

外观模式包含以下角色:
Facade: 外观角色
SubSystem:子系统角色

11.亨元模式                                                                                            

在一个系统中对象会使得内存占用过多,特别是那些大量重复的对象,这就是对系统资源的极大浪费。享元模式对对象的重用提供了一种解决方案,它使用共享技术对相同或者类似对象实现重用。享元模式就是运行共享技术有效地支持大量细粒度对象的复用。系统使用少许对象,并且这些都比较类似,状态变化小,能够实现对象的屡次复用。这里有一点要注意:享元模式要求可以共享的对象必须是细粒度对象。享元模式经过共享技术使得系统中的对象个数大大减小了,同时享元模式使用了内部状态和外部状态,同时外部状态相对独立,不会影响到内部状态,因此享元模式可以使得享元对象在不一样的环境下被共享。同时正是分为了内部状态和外部状态,享元模式会使得系统变得更加复杂,同时也会致使读取外部状态所消耗的时间过长。

享元模式包含以下角色:
Flyweight: 抽象享元类
ConcreteFlyweight: 具体享元类
UnsharedConcreteFlyweight: 非共享具体享元类
FlyweightFactory: 享元工厂类

12.代理模式                                                                                        

 代理模式就是给一个对象提供一个代理,并由代理对象控制对原对象的引用。它使得客户不能直接与真正的目标对象通讯。代理对象是目标对象的表明,其余须要与这个目标对象打交道的操做都是和这个代理对象在交涉。

代理对象能够在客户端和目标对象之间起到中介的做用,这样起到了的做用和保护了目标对象的,同时也在必定程度上面减小了系统的耦合度。

代理模式包含以下角色:
 Subject: 抽象主题角色
 Proxy: 代理主题角色
 RealSubject: 真实主题角色

13.访问者模式                                                                             

访问者模式俗称23大设计模式中最难的一个。除告终构复杂外,理解也比较难。在咱们软件开发中咱们可能会对同一个对象有不一样的处理,若是咱们都作分别的处理,将会产生灾难性的错误。对于这种问题,访问者模式提供了比较好的解决方案。访问者模式即表示一个做用于某对象结构中的各元素的操做,它使咱们能够在不改变各元素的类的前提下定义做用于这些元素的新操做。

访问者模式的目的是封装一些施加于某种数据结构元素之上的操做,一旦这些操做须要修改的话,接受这个操做的数据结构能够保持不变。为不一样类型的元素提供多种访问操做方式,且能够在不修改原有系统的状况下增长新的操做方式。同时咱们还须要明确一点那就是访问者模式是适用于那些数据结构比较稳定的,由于他是将数据的操做与数据结构进行分离了,若是某个系统的数据结构相对稳定,可是操做算法易于变化的话,就比较适用适用访问者模式,由于访问者模式使得算法操做的增长变得比较简单了。

访问者模式包含以下角色:
Vistor: 抽象访问者
ConcreteVisitor: 具体访问者
Element: 抽象元素
ConcreteElement: 具体元素 
ObjectStructure: 对象结构

14.模板模式                                                                               

有些时候咱们作某几件事情的步骤都差很少,仅有那么一小点的不一样,在软件开发的世界里一样如此,若是咱们都将这些步骤都一一作的话,费时费力不讨好。因此咱们能够将这些步骤分解、封装起来,而后利用继承的方式来继承便可,固然不一样的能够本身重写实现嘛!这就是模板方法模式提供的解决方案。

所谓模板方法模式就是在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类能够在不改变算法结构的状况下,从新定义算法中的某些步骤。

模板方法模式就是基于继承的代码复用技术的。在模板方法模式中,咱们能够将相同部分的代码放在父类中,而将不一样的代码放入不一样的子类中。也就是说咱们须要声明一个抽象的父类,将部分逻辑以具体方法以及具体构造函数的形式实现,而后声明一些抽象方法让子类来实现剩余的逻辑,不一样的子类能够以不一样的方式来实现这些逻辑。因此模板方法的模板其实就是一个普通的方法,只不过这个方法是将算法实现的步骤封装起来的。

模板方法模式包含以下角色:
AbstractClass: 抽象类 
ConcreteClass: 具体子类

15.策略模式                                                                              

 咱们知道一件事可能会有不少种方式来实现它,可是其中总有一种最高效的方式,在软件开发的世界里面一样如此,咱们也有不少中方法来实现一个功能,可是咱们须要一种简单、高效的方式来实现它,使得系统可以很是灵活,这就是策略模式。

因此策略模式就是定义了算法族,分别封装起来,让他们以前能够互相转换,此模式然该算法的变化独立于使用算法的客户。

在策略模式中它将这些解决问题的方法定义成一个算法群,每个方法都对应着一个具体的算法,这里的一个算法我就称之为一个策略。虽然策略模式定义了算法,可是它并不提供算法的选择,即什么算法对于什么问题最合适这是策略模式所不关心的,因此对于策略的选择仍是要客户端来作。客户必需要清楚的知道每一个算法之间的区别和在何时什么地方使用什么策略是最合适的,这样就增长客户端的负担。

同时策略模式也很是完美的符合了“开闭原则”,用户能够在不修改原有系统的基础上选择算法或行为,也能够灵活地增长新的算法或行为。可是一个策略对应一个类将会是系统产生不少的策略类。

策略模式包含以下角色:
Context: 环境类
Strategy: 抽象策略类
ConcreteStrategy: 具体策略类

16.状态模式                                                                         

 在不少状况下咱们对象的行为依赖于它的一个或者多个变化的属性,这些可变的属性咱们称之为状态,也就是说行为依赖状态,即当该对象由于在外部的互动而致使他的状态发生变化,从而它的行为也会作出相应的变化。对于这种状况,咱们是不能用行为来控制状态的变化,而应该站在状态的角度来思考行为,便是什么状态就要作出什么样的行为。这个就是状态模式。

因此状态模式就是容许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类。

在状态模式中咱们能够减小大块的if…else语句,它是容许态转换逻辑与状态对象合成一体,可是减小if…else语句的代价就是会换来大量的类,因此状态模式势必会增长系统中类或者对象的个数。

同时状态模式是将全部与某个状态有关的行为放到一个类中,而且能够方便地增长新的状态,只须要改变对象状态便可改变对象的行为。可是这样就会致使系统的结构和实现都会比较复杂,若是使用不当就会致使程序的结构和代码混乱,不利于维护。

 

 状态模式包含以下角色:
Context: 环境类
State: 抽象状态类
ConcreteState: 具体状态类

17.观察者模式                                                                               

何谓观察者模式?观察者模式定义了对象之间的一对多依赖关系,这样一来,当一个对象改变状态时,它的全部依赖者都会收到通知而且自动更新。

在这里,发生改变的对象称之为观察目标,而被通知的对象称之为观察者。一个观察目标能够对应多个观察者,并且这些观察者之间没有相互联系,因此么能够根据须要增长和删除观察者,使得系统更易于扩展。因此观察者提供了一种对象设计,让主题和观察者之间以松耦合的方式结合。

 

 观察者模式包含以下角色:
Subject: 目标
ConcreteSubject: 具体目标
Observer: 观察者
ConcreteObserver: 具体观察者

18.备忘录模式                                                                          

 后悔药人人都想要,可是事实倒是残酷的,根本就没有后悔药可买,可是也不只如此,在软件的世界里就有后悔药!备忘录模式就是一种后悔药,它给咱们的软件提供后悔药的机制,经过它可使系统恢复到某一特定的历史状态。

所谓备忘录模式就是在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象以外保存这个状态,这样能够在之后将对象恢复到原先保存的状态。它实现了对信息的封装,使得客户不须要关心状态保存的细节。保存就要消耗资源,因此备忘录模式的缺点就在于消耗资源。若是类的成员变量过多,势必会占用比较大的资源,并且每一次保存都会消耗必定的内存。

 

备忘录模式包含以下角色:
Originator: 原发器
Memento: 备忘录
Caretaker: 负责人

19.中介者模式                                                                       

 租房各位都有过的经历吧!在这个过程当中中介结构扮演着很重要的角色,它在这里起到一个中间者的做用,给咱们和房主互相传递信息。在外面软件的世界里一样须要这样一个中间者。在咱们的系统中有时候会存在着对象与对象之间存在着很强、复杂的关联关系,若是让他们之间有直接的联系的话,一定会致使整个系统变得很是复杂,并且可扩展性不好!在前面咱们就知道若是两个类之间没有没必要彼此通讯,咱们就不该该让他们有直接的关联关系,若是实在是须要通讯的话,咱们能够经过第三者来转发他们的请求。一样,这里咱们利用中介者来解决这个问题。

所谓中介者模式就是用一个中介对象来封装一系列的对象交互,中介者使各对象不须要显式地相互引用,从而使其耦合松散,并且能够独立地改变它们之间的交互。在中介者模式中,中介对象用来封装对象之间的关系,各个对象能够不须要知道具体的信息经过中介者对象就能够实现相互通讯。它减小了对象之间的互相关系,提供了系统可复用性,简化了系统的结构。

 在中介者模式中,各个对象不须要互相知道了解,他们只须要知道中介者对象便可,可是中介者对象就必需要知道全部的对象和他们之间的关联关系,正是由于这样就致使了中介者对象的结构过于复杂,承担了过多的职责,同时它也是整个系统的核心所在,它有问题将会致使整个系统的问题。因此若是在系统的设计过程当中若是出现“多对多”的复杂关系群时,千万别急着使用中介者模式,而是要仔细思考是否是您设计的系统存在问题。

Mediator: 抽象中介者
ConcreteMediator: 具体中介者
Colleague: 抽象同事类
ConcreteColleague: 具体同事类

20.迭代器模式                                                                              

对于迭代在编程过程当中咱们常常用到,可以游走于聚合内的每个元素,同时还能够提供多种不一样的遍历方式,这就是迭代器模式的设计动机。在咱们实际的开发过程当中,咱们可能会须要根据不一样的需求以不一样的方式来遍历整个对象,可是咱们又不但愿在聚合对象的抽象接口中充斥着各类不一样的遍历操做,因而咱们就但愿有某个东西可以以多种不一样的方式来遍历一个聚合对象,这时迭代器模式出现了。

何为迭代器模式?所谓迭代器模式就是提供一种方法顺序访问一个聚合对象中的各个元素,而不是暴露其内部的表示。迭代器模式是将迭代元素的责任交给迭代器,而不是聚合对象,咱们甚至在不须要知道该聚合对象的内部结构就能够实现该聚合对象的迭代。

经过迭代器模式,使得聚合对象的结构更加简单,它不须要关注它元素的遍历,只须要专一它应该专一的事情,这样就更加符合单一职责原则了。

迭代器模式包含以下角色:
Iterator: 抽象迭代器
ConcreteIterator: 具体迭代器
Aggregate: 抽象聚合类
ConcreteAggregate: 具体聚合类

21.解释器模式                                                                            

所谓解释器模式就是定义语言的文法,而且创建一个解释器来解释该语言中的句子。解释器模式描述了如何构成一个简单的语言解释器,主要应用在使用面向对象语言开发的编译器中。它描述了如何为简单的语言定义一个文法,如何在该语言中表示一个句子,以及如何解释这些句子。

解释器模式包含以下角色:
AbstractExpression: 抽象表达式
TerminalExpression: 终结符表达式
NonterminalExpression: 非终结符表达式
Context: 环境类
Client: 客户类

22.命令模式                                                                                

 有些时候咱们想某个对象发送一个请求,可是咱们并不知道该请求的具体接收者是谁,具体的处理过程是如何的,们只知道在程序运行中指定具体的请求接收者便可,对于这样将请求封装成对象的咱们称之为命令模式。因此命令模式将请求封装成对象,以便使用不一样的请求、队列或者日志来参数化其余对象。同时命令模式支持可撤销的操做。

命令模式能够将请求的发送者和接收者之间实现彻底的解耦,发送者和接收者之间没有直接的联系,发送者只须要知道如何发送请求命令便可,其他的能够一律无论,甚至命令是否成功都无需关心。同时咱们能够很是方便的增长新的命令,可是可能就是由于方便和对请求的封装就会致使系统中会存在过多的具体命令类。

命令模式包含以下角色:
Command: 抽象命令类
ConcreteCommand: 具体命令类
Invoker: 调用者
Receiver: 接收者
Client:客户类

23.责任链模式                                                                         

职责链模式描述的请求如何沿着对象所组成的链来传递的。它将对象组成一条链,发送者将请求发给链的第一个接收者,而且沿着这条链传递,直到有一个对象来处理它或者直到最后也没有对象处理而留在链末尾端。

避免请求发送者与接收者耦合在一块儿,让多个对象都有可能接收请求,将这些对象链接成一条链,而且沿着这条链传递请求,直到有对象处理它为止,这就是职责链模式。在职责链模式中,使得每个对象都有可能来处理请求,从而实现了请求的发送者和接收者之间的解耦。同时职责链模式简化了对象的结构,它使得每一个对象都只须要引用它的后继者便可,而没必要了解整条链,这样既提升了系统的灵活性也使得增长新的请求处理类也比较方便。可是在职责链中咱们不能保证全部的请求都可以被处理,并且不利于观察运行时特征。

 

职责链模式包含以下角色:
Handler: 抽象处理者
ConcreteHandler: 具体处理者
Client: 客户类

5、如何学习设计模式                                                                

①    学习技巧

学习设计模式时,有一些技巧可以帮助你快速理解设计模式。

a)   使用较简单的面向对象的语言如Java、C#。GoF的[设计模式]实质上是面向对象的设计模式。[GoF·1.1]中提到“程序设计语言的选择很是重要,它将影响人们理解问题的出发点”。从学习设计模式的角度看,Java和C#较C++更容易一些。好比Java接口等,可以更有效展示设计模式的意图。

b)   使用工具BlueJ。BlueJ最大的好处,就是提供了简单的类图。正如我在简明设计模式Java中所作的,较少去专门画类图,而是在BlueJ中截图。在学生上机编写演示程序时,经常先看他的类图,以判断他的程序是否正确,必要时再看源代码。

c)   平常生活的隐喻。用一些实际生活中的例子来讲明某某模式,可以让你快速掌握某模式的目的和实现代码的结构。同时,你要认识到,这种隐喻如同告诉你(2+3)2=22+2*2*3+32,你须要本身触类旁通,得出(a+b)2=a2+2ab+b2。在实际工做中的模式的具体应用,则至关于应用代数公式。

d)    动手实践和怀疑精神。看显浅的参考书或上网查阅资料时,要本身敲(复制也能够)代码并运行,要多修改别人的源代码提出本身的观点:为何书中不这样设计、为何要那样设计;若是增添一些方法、方法参数、或成员变量会如何?必需要本身亲自动手,最起码要运行。另外,要勇于向博主提问、拍砖。你甚至能够质疑GoF的某些章节的解说和意图,更况且一些博主呢。

②    基础知识

这些知识让你知道,设计模式好在何处。

a)    面向对象范式。也就是人们传说的思想。封装、继承和多态这些东西,在我看来比if、for等稍微高一点,也属于语法问题。面向对象编程要掌握的三大原则柏拉图(Plato)原则、里氏(Liskov)替换原则和Parnas原则。这三个原则其实很是简单。任何原则,你以为很难一见倾心,很难快速认同,那它就不会是好原则。

b)    设计原则。许多人列举了7大原则,如单一职责原则、开闭原则、里氏代换原则、依赖倒转原则、接口隔离原则、合成复用原则、迪米特法则。LSP,我将它提高为面向对象范式的3大基石之一;单一职责和接口隔离,主要做为面向对象分析/OOA时职责划分所遵循的原则,此时你能够不太在乎。依赖倒转原则,我把它做为垃圾扔掉,由于开闭原则或者直接地说“依赖于抽象类型原则”已经包含了依赖倒转原则的精华,而依赖倒转原则的糟粕由IoC继承。固然,回调,我很强调。因此,你要掌握的有抽象依赖原则(OCP)、单向依赖原则(含对回调的学习)和最低依赖原则(合成复用原则、迪米特法则)

c)    UML的初步了解。这是学习设计模式的工具。在早期,你甚至能够仅了解BlueJ的相关图示,也就10分钟的事情。

③    境界

《五灯会元》卷十七中,有一则唐朝禅师青原唯信禅师的语录:“老僧三十年前未参禅时,见山是山,见水是水。及至后来亲见知识,有个入处,见山不是山,见水不是水。而今得个休歇处,依前见山只是山,见水只是水。”

a)    仔细研究GoF的[设计模式],逐个学习其意图和结构,是一个抱着字典学习英语的方式。见山是山,见水是水,致使你可能在实际工做中生搬硬套、东施效颦。

b)    建议从简单的场景出发,本身发现或设计出某种模式。你从中体会该模式是如何解决问题的,这样,该模式成为你本身的东西,你才不会出现知易行难的问题。全部的设计模式不过是基本原则和理念在特定场合的应用。你可能不知道某个设计模式的名字,可是你知道它一切的优缺点和变体以及应用场合。见山不是山,见水不是水。

c)     你对基本原则和理念融会贯通,你能够可惜:“我找到一种模式,原来在[设计模式](实际上是某个特殊的书、文章提到的模式)中早就有了这种模式”。这时,模式不模式又如何呢?反模式又怎样。看见一个模式,你会说:“嗯,这是一种有用的模式”。见山只是山,见水只是水。

以上一点浅见。


注:【】中的内容是我加的。

1 转录【IT168知识库】

         发现不少初学设计模式的人都有一些特色就是学习了某个设计模式以后,貌似理解了,可是殊不知道怎么去使用这些所谓的精华经验,苦于不知如何下手。我最初学习设计模式的时候也有相似的经验,我将个人经验分享出来,但愿能对初学者有帮助。
        我对设计模式产生兴趣是在大概一年之前,最初看书的时候好像是看懂了,大概知道他在说什么。看了几个模式以后就开始寻找时机来套用套用这些模式。结果是除了Singleton模式之外的其余模式都没有找到应用的场所。而后我就没开始看下去了,我知道再看也没用,可是我并无放弃对设计模式的关注。
        不久我就在MSDN的Webcast上看到李建忠的 C#面向对象设计模式纵横谈讲座,很不错的系列讲座,让我对设计模式有了新的理解。我意识到学习设计模式,确切的讲是学习面向对象的设计模式,应该从学习面向对象开始。【面向对象的原理如同了解下象棋的规则,而设计模式至关于残局,不知道规则看什么残局】因为以前一年都在作asp.net开发,虽然都是在写类、学着duwamish搞分层架构、搞类型化DataSet、也弄过自定义实体类,但好像一年下来还没怎么用过接口,什么多态也是极少用。事实上对面向对象的编程思想的认识仍是很模糊的。
        从新认识OO:面向对象编程是一种思想,以面向对象的思惟来思考软件设计结构,从而强化面向对象的编程范式。面向对象的特色是封装,继承,多态【这些也算?】。因此从那是开始,当我设计一个类的时候,不断的提示本身如下三点:
第一:别把本身的数据公开,除非你要向别人提供数据,使用尽可能低的访问权限。
第二:以一个外部的视角来看类,紧记不要要求别人要在知道你是怎么实现一个方法以后才能使用个人类。
第三:分清类的职责,该这个类作的事情就要在这个类中实现,不应个人类作的事情就让别的类去实现。
在这三点的指导下来写类,写程序开始像在作“设计”了^_^。
一段时间后对设计模式就慢慢有感受了,并可以找到一些设计模式的应用场景了。并常套用套用那些模式,逐渐的加深对模式的理解,并把它变成本身的东西,可以在其余的地方灵活的用起来。

2. 转录 《易学设计模式·1.4  如何学习设计模式》郭志学 人民邮电出版社

如何学习设计模式
在了解了设计模式的历史和分类后,应该如何学习设计模式呢?在学习设计模式以前,读者必定要树立一种意识,那就是:设计模式并不仅是一种方法和技术,它更是一种思想、一个方法论。它和具体的语言没有关系,学习设计模式最主要的目的就是要创建面向对象的思想,尽量地面向接口编程、低耦合、高内聚,使你设计的程序尽量地复用。【似是而非。学习设计模式可以更好理解面向对象的思想,设计模式是一些设计的技巧和窍门,不要上升到思想、方法论好很差
有些软件开发人员,在程序设计时,总想着往某个设计模式上套,其实这样是不对的,并无真正掌握设计模式的思想。其实不少时候读者用了某种设计模式,只是本身不知道这个模式叫什么名字而已。所以,在程序设计时,要根据本身的理解,使用合适的设计模式。
而有另一些软件开发人员,在程序设计时,动不动就给类起个相似模式的名字,好比叫某某Facade、某某Factory等,其实类里面的内容和设计模式根本没有一点关系,只是用来标榜本身懂设计模式而已。
所以,学习设计模式,首先要了解有哪些方面的设计模式能够供开发人员使用,而后再分别研究每一个设计模式的原理,使用时机和方法,也就是说要在什么状况下才使用某个设计模式,在了解某个设计模式的使用时机时,还要了解此时若是不使用这个设计模式,会形成什么样的后果。当对每一个模式的原理和使用方法都了解了之后,更重要的是,学习面向对象的思想方式,在掌握面向对象的思想方式后,再回过头来看设计模式,就会有更深入的理解,最后,学习设计模式,必定要勤学多练。【就最后一句很赞同】

 

6、我的感悟                                                                       

学习设计模式确实有几种境界:

第一种是学习了一两个设计模式,就一直想用到本身的代码中去;

第二种是学彻底部设计模式,以为不少模式都很类似,分不清楚它们之间有什么区别;

第三种是灵活运用设计模式,就算不用具体哪一种模式也能够设计也高质量的代码,无剑胜有剑。

最后附上总结图:

相关文章
相关标签/搜索