什么是设计模式 创建型模式 结构型模式 对象行为型模式

什么是设计模式

模式:在我们身边重复发生的问题,以及解决这些问题的方案和核心内容.\r\n设计模式:软件设计过程中,设计到的常用问题,以及解决这些问题的方案和核心内容。\r\n设计模式4要素:\r\n名称 :记录这个模式相关的问题和解决方案等。\r\n问题的描述: 具体的问题的描述。\r\n解决方案: 如何解决这类问题,包括设计涉及的组成成分,已经这些部分的职责和相互关系。\r\n效果 :模式应用的效果以及应用过程中应该权衡的问题。

设计模式的分类

创建型模式

解决了一个系统中如何创建、组合和表示其中的对象。类创建模式改变被实例化的类,对象创建模式改变具体实例化的对象。\r\n模式的封装性,整个系统关心的只是相应的接口:\r\n把系统中使用哪些具体的类的信息封装起来\r\n隐藏了系统中这些类是如何被创建和组合在一起的细节\r\n类别\r\nSingleton(单例模式)\r\nFactory Method (工厂方法)\r\nAbstract Factory(抽象工厂)\r\nBuilder(生成器)\r\nPrototype(原型)

结构型模式

结构型模式涉及到面向对象设计中如何组织类和对象的结构,描述了如何对一些对象进行组合,以达到一些新的功能。\r\n类别:

行为型模式

行为模式涉及算法和对象间职责的分配,不仅描述类和对象的模式,还表示他们之间的通信模式。\r\n分类:\r\n行为类模式:使用继承机制在类间分配行为。如Template Method(算法的抽象定义)和Interpreter模式(解释器)。\r\n行为对象模式:使用对象复合而不是继承。描述一组对等的对象怎样相互协作以完成一个单独对象不能完成的任务。如Observer模式,Strategy模式,Command模式,Visitor模式等等

Observer模式

目的:定义对象间一对多的依赖关系,当一个对象变化时,所有依赖他的对象都得到通知而自动更新。\r\n问题描述:在MVC架构中,模型和视图分离。但是他们并不是相互独立的,当用户改变模型数据的信息时需要视图做相应的更新,反过来也是。\r\n解决方案:Observer模式,有对应的目标类和观察者类,一个目标有多个依赖他的观察者的对象。一旦一个目标的状态发生变化时,所有的观察者需要得到通知。作为通知的响应,观察者做相应的处理。

简单来说,Observer模式让一个对象(观察者,Observer)去监视另一个对象(目标,Subject);它使得目标和观察者之间建立一种 “发布--订阅”(publish-subscribe )的关系。通过Observer模式,观察者可以向目标登记,表明自己要从目标接收事件。目标需要向观察者通知事件时,只是简单地将事件发给每一个观察者。 例如,有一个基于某种数据模型的电子表格。只要数据模型发生变化,电子表格就需要更新表格单元以及内嵌的图表。这个例子中,目标是数据模型,观察者是表格单元和图表。当观察者接收到数据模型已经变化的通知时,它们就更新自己。 Observer模式的好处是:它解除了观察者和目标之间的耦合关系。目标不需要知道它的观察者的任何信息。相反,目标只是允许观察者订阅事件。当目标产生一个事件时,它简单地将事件传给每一个观察者。

Chain of responsibility(责任链模式)

目的:把可能处理请求的对象组合成一条链,并沿着这条链把请求发下去,直到找到对象处理请求为止。\r\n例子.

Strategy 策略模式

目的:定义一系列的算法,把他们封装起来,并且使他们可以相互转换。\r\n描述:比如有很多算法对文本进行压缩。但是在设计中进行硬性编码是不可取的。一来代码冗长,二来不可替换等等。\r\n解决:定义一系列的类来封装不同的算法。以这种方式封装算法就叫一个策略。

设计模式的几大原则

开-闭原则\r\n里氏代换原则\r\n依赖倒转原则\r\n接口隔离原则\r\n合成/聚合复用原则\r\n迪米特法则

开-闭原则

一个软件应当对扩展开放对修改关闭\r\n在设计一个模块的时候应当使这个模块可以在不被修改的前提下被扩展。就是说可以在不必修改源代码的情况下改变这个模块的行为。\r\n优越性:\r\n1.通过扩展已有的系统,可以提供新的行为\r\n,使变化中的软件系统有一定的适用性和灵活性。\r\n    2.已有的软件模块,特别是最重要的抽象层模块不能再修改,使得变化中的软件系统有一定的稳定性和延续性。\r\n策略模式是对开闭原则的很好诠释 ,其他还有工厂模式、建造模式、桥接模式、门面模式等.

里氏代换原则(LSP)

一个软件实体如果使用的是一个基类的话,那么一定适用与其子类,而且它根本不能查决出基类对象和子类对象的区别。\r\n该原则是继承复用的基石。只有当衍生类可以替换掉其基类,软件单位的功能不会受到影响,基类才能真正被复用,而衍生类才能够再基类的基础上增加新的行为。

依赖倒转原则(DIP)

依赖倒转原则的表述是: 抽象不应当依赖于细节,细节应当依赖于抽象。 要针对接口编程,不要针对实现编程.

依赖倒转原则的表述

抽象不应该依赖于细节,而是细节依赖于抽象。\r\n要针对接口编程,不要针对实现编程。\r\n就是变量的声明,方法返回类型,参量的类型声明等要使用接口或者抽象类,而不要用具体类。

接口隔离原则

使用多个专门的接口比使用单一的总接口好\r\n一个类对另外一个类的依赖性应该是建立在最小的接口上。\r\n一个类可能实现不同的接口,在定义的过程中尽量让一个接口尽量只代表一个角色。而在代码中尽量使用其中一个接口,就是在这段代码中该对象代表这一个角色。尽量不要使用一个代表多个角色的大角色,耦合度太高。

合成/聚合复用原则(CARP)

要尽量使用合成/聚合原则,而不是继承关系达到软件复用的目的。\r\n聚合用来表示“拥有”或整体与部分的关系,而合成则用来表示一种强得多的“拥有”关系。在一个合成关系里,部分和整体的生命周期是一样的。合成就象所说的“合成品”,拆开就坏 .\r\n继承复用的缺点:\r\n1.继承复用破坏包装,因为继承将超类细节暴露给子类。\r\n2.如果超类实现发生改变,子类也不得不发生改变。\r\n3.从超类继承而来的实现时静态的,不可能在运行时间内发生改变,因此没有足够的灵活性。

聚合(Aggregation):\r\n   这是一种松散的对象间的关系.举个例子:计算机和他的外围设备就是一例.\r\n  用来表示拥有关系或者整体与部分的关系。\r\n合成(Composition):\r\n这是一种非常强的对象间的关系,举个例子,树和它的树叶之间的关系.\r\n在一个合成里,部分与整体的生命周期都是一样的。一个合成的新对象完全拥有对其组成\r\n部分的支配权。包括他们的创建和毁灭。\r\n最后总结一下:\r\n聚合:\r\n 聚合有时能够不依赖部分而存在,有时又不能 \r\n部分可以独立于聚合而存在 \r\n如果有一部分遗失,聚合会给人一种不完全的感觉 \r\n部分的所有权可以由几个聚合来共享,比如打印机

合成 :Java中实现“多继承”策略         class   A{         public   String   get(){return   "A";}         .............     }     class   B{         public   String   get(){return   "A";}         ..............     }     class   C{         public   String   get(){return   "A";}         ...............     }         class   D {         private   A   a   =   new   A();         private   B   b   =   new   B();         private   C   c   =   new   C();         public   String   get(){return   "D:"       a.get();}         ....     }         D就是一种合成模式,你也可以认为D继承了ABC的所有方法

迪米特法则(LoD)

又称最少知识原则,就是说一个对象应当对其他对象有尽可能少的了解。\r\n一个软件实体应当尽可能少的与其他实体发生相互作用。\r\n每一个软件单位对其他的单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位。\r\n\r\n迪米特法则的初衷在于降低类之间的耦合。由于每个类尽量减少对其他类的依赖,因此,很容易使得系统的功能模块功能独立,相互之间不存在(或很少有)依赖关系。