详解23种设计模式

设计模式(Design Patterns)

  首先说一下我对设计模式的理解,设计模式是一种在软件内部优化代码的技巧。注意,是代码的内部,也就是在一个局部范围内优化设计。这一点和软件的架构是完全不同的,软件架构是全局的优化,讲的是怎么对软件进行切分以及对切开之后的内容进行重组的一个过程。软件的设计模式强调的是代码,软件架构强调的是结构。在面向对象的编程思想中,这就体现在怎么解决类与类之间的关系。能处理好类与类之间的关系,优化设计就搞好了。下面这段话是软件设计模式的定义:

  设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。

   毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理的运用设计模式可以完美的解决很多问题,每种模式在现在中都有相应的原理来与之对应,每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是它能被广泛应用的原因。设计模式是一代又一代的编程大师总结出来的,我们应该重视,不能束之高阁,应当合理利用。关键是要搞清楚哪种情况用哪种设计模式。

一、设计模式的分类

总体来说设计模式分为三大类:

创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。(还有一种叫简单工厂模式,是工厂模式的变形,不满足单一职责,设计不太合理,所以就没列出来)

结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

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

 

 

二、设计模式的七大原则

设计模式的七大原则堪称经典,这七条原则是我们在设计软件的过程中必须准守的,当然不遵守的话,你的老板可能就会“嘿嘿”你,你懂得!这七条原则指导了23种设计模式,可以这么说,23种设计模式就是在这七条原则在不同场景之下的应用。而且,衡量一个设计模式的好坏,就是看他满不满足这七条设计原则。我们在写代码的时候,不一定非要用23种设计模式种的一种或多种,但是一定要准守这七条设计原则。

1、开闭原则(Open Close Principle)

开闭原则,是对扩展开放对修改关闭。这是一条很重要的原则,我们很多代码的设计都要用到这条原则。这一原则是为了保证系统的可维护性。也就是可以修改。这条原则要求我们在不修改原有代码的基础上增加新的功能,当然要增加新的代码,只是不修改原来的代码。

2、里氏代换原则(Liskov Substitution Principle)

里氏代换原则说,凡是父类出现的地方,子类一定可以代替父类。也就是说,父类的引用(指针)可以指向子类的对象。那么一个父类有多个子类的话,在程序运行的过程中,是不是可以动态的指向不同的子对象呢?这样就实现了修改。在不同的子类里面写不同的方法,然后通过动态的引用,实现动态的调用不同的方法。开闭原则告诉我们要做到对修改关闭对扩展开放,而李氏代换原则则告诉我们怎么是具体的开闭原则。

3、依赖倒转原则(Dependence Inversion Principle)

依赖倒转原则就是要求我们进行分层,而且层与层之家不能之间相互依赖,而应该是都依赖于一个接口,一旦某一层出错或者是崩溃,对错误层维护即可,不用改动和错误层相关的层。

4.单一职责原则

单一职责原则是说一个类或者是一个实体或者是一个方法做的事情要单一,不能太复杂。

5、接口隔离原则(Interface Segregation Principle)

接口隔离原则是说我们要用接口,而且要适当的用接口。不能把一个接口写得太大,接口也要保证单一职责原则。

6、迪米特法则(最少知道原则)(Demeter Principle)

为什么叫最少知道原则,就是说:一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。

7、合成复用原则(Composite Reuse Principle)

原则是尽量使用合成/聚合的方式,而不是使用继承。

三、Java的23中设计模式

从这一块开始,我们详细介绍Java中23种设计模式的概念,应用场景等情况,并结合他们的特点及设计模式的原则进行分析。

****************************************************************创建型模式**************************************************************************

   1.工厂方法模式:抽象出一个父工厂类作为所有工厂类的基类,抽象出一个父产品类作为所有产品类的基类,每种工厂只生产一种产品,工厂和产品之间是关联关系。类图如下

  

   抽象工厂模式,抽象工厂模式是对工厂模式的一次升级,工厂模式一个工厂只能生产一种产品,抽象工厂模式中,一个工厂可以生产多种产品。我们必须理解两个概念,产品等级结构和产品族。产品等级结构指的是产品的种类,一种产品就是一个产品等级结构,产品族指的是产品的工厂,一家工厂就是一个产品族。其他的和工厂模式基本一致。类图如下

   建造者模式:建造者模式可能没有工厂模式好理解,这种设计模式适合于要考虑对象创建细节的情形使用。工厂模式中用户只需向对象工厂发出创建对象的请求就可获取需要的对象,但是有的用户不仅要创建对象,还对创建对象的细节比较关心,这个设计模式引入了一个指挥者类,指挥者指挥工厂构建对象的具体细节,真正创建对象的建造者按照指挥者的方法来建造并且组装,把组装好的产品交给指挥者,然后指挥者交给用户。类图如下:

   原型模式,考虑这种情况,一个类的属性特别多,而且这个类实例化的对象属性值大部分都相同或者说很相似。我们创建这么一个类最头疼就是给它赋值了。用全构造方法,初始化的时候还不知道所有的属性值,用set方法,又太复杂。有没有这样的一张方法呢,能够让我们“复制”一个现有的对象,我们复制回来的这个对象的属性稍微改改不就行了吗。原型模式就是为了解决这个问题的。原型模式分为深克隆和浅克隆。深克隆指的是实例化一个新对象,然后把原对象的数据赋值给新对象,浅克隆指的是新对象的引用直接指向原对象。类图如下:

   单例模式,这个模式非常有用。有的类很耗资源,我们就需要把它配置成单例的。单例模式的代码也和独特,私有的构造方法,公有的get方法。类图如下

***************************************************************************************************************************************************   

适配器模式,适配器模式的任务就是转换,用户需要的接口和当前类所提供的接口不一致的时候我们就要使用适配器模式,这种开发模式多用于二次开发中,由于原来的接口不适用,而且也不愿意修改原来的设计方式,那就接上适配器来满足用户的需求。而且,不同的用户可以加上不同的适配器。

   桥接模式,这种模式的使用范围也很大。考虑这种情况,引起一个事物变化的因素不只有一种,比如说,用户要定制一支笔,笔的颜色有10种,笔的尺寸有3种,这样笔的类型就有30种。我们选择引起变化的主要因素作为基类,用它来引用次要变化的因素。

   组合模式,结构型模式。组合模式组合了多个对象形成树形结构来表示“整体-部分”的结构层次。它将单个对象和组合对象的使用一致化,将对象组织到树结构中。

   装饰模式,结构型模式。在被装饰的类中调用在装饰器类中定义的方法,实现更多更复杂的功能,也就是说装饰模式可以在不需要创造更多子类的情况下,将对象的功能加以扩展。

   外观模式,结构型模式。外观模式定义了一个高层接口一个统一的接口,使得外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面。就像是一个网站,我们用户都是通过首页进入任意的子栏目的,并不需要记住每一个子栏目的地址进入。

   享元模式,结构型模式。系统只使用少量的很相似、状态变化很小,可以实现对象多次复用的对象。运用共享技术有效地支持大量细粒度对象的复用。

   代理模式,结构型模式。如果一个客户并不想直接引用一个对象,就可以通过一个称之为“代理”的第三者来实现间接引用。代理对象其实可以看做在客户端和目标对象之间起到中介的作用。给某一个对象提供一个代理,并由代理对象控制对原对象的引用。

   职责链模式,行为型模式。职责链可以使一条直线,一个环或者一个树形结构,沿着这条单向的链来传递请求,而链上的每一个对象都是请求处理者,职责链模式将请求的处理者组织成一条链,并使请求沿着链传递,由链上的处理者对请求进行相应的处理。职责链模式避免了请求发送者与接受者发生碰撞,使多个对象都有可能接受请求,进行相应的处理。

   命令模式,行为型模式。命令模式将发送者与接收者完全解耦,使两者之间没有直接引用的关系。命令模式将一个请求封装为一个对象,从而使我们可以使用不同的请求对客户进行参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。

   解释器模式,行为型模式。定义语言的文法,并且建立一个解释器来解释该语言中的句子,这个“语言”的含义就是使用规定格式和语法的代码。

 

   迭代器模式,行为型模式。举个例子,如果将电视机看成一个视频频道的集合,那么迭代器就相当于是电视机遥控器。我们可以通过遥控器对电视频道进行操作。迭代器模式提供了一种方法来访问聚合对象,但是不用暴露对象的内部表示。

 

   中介者模式,行为型模式。顾名思义,就是通过一个中介者中介对象来封装一系列的对象交互,使各对象不需要显式地相互引用,可以独立地改变它们之间的交互。

 

   备忘录模式,行为型模式。就像是可以撤销历史操作一样的功能,备忘录模式在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样就可以在以后将对象恢复到原先保存的状态。

   观察者模式,行为型模式。将发生改变的对象成为观察目标,而被通知的对象称为观察者。观察者模式定义了一种对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关的依赖对象可以得到通知并被自动更新。

   状态模式,行为型模式。一个对象在其内部的状态发生改变时要改变它的行为,即状态和行为不可以分离。

 

   策略模式,行为型模式。定义一系列算法,并且进行封装,这样就可以让它们进行相互替换。保证这些策略的一致性,使用一个抽象类做算法的定义。

   模板方法模式,行为型模式。定义一个操作中算法的骨架,作为父类模板,在子类中不改变一个算法的结构只是进行重定义该算法的某些特定步骤完成具体算法。

   访问者模式,行为型模式。封装一些施加于某种数据结构元素之上的操作,一旦操作被修改,可以保持结构不变,使我们可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

 

 
posted @ 2017-04-02 08:18  学计算机的人绝不认输  阅读(2057)  评论(0编辑  收藏  举报