一句话解释设计模式

学习设计模式的第一感受就是,我原来好好的代码(或者说是很简单的代码),非得套用这么复杂的写法去实现,简直是脱了裤子放屁

相信很多人应该有和我一样的想法,在这里首先我们要明确,这么复杂的设计模式一定是有用的,在你未成为大牛之前,一定要相信大牛一定是对的.那他的作用是什么呢?首先要了解面向对象的六大原则

我们javaer核心编程思想就是面向对象,也就是你的代码要面向对象,能new对象可以说已经面向对象入门了,但是代码依然不够面向对象,不够爽,一套能让人爽的代码,要基于以下几个原则

第一原则:千万不要XB优化你的代码,慢慢等待时机,一两句代码就解决的事,千万不要涉及设计模式,不要管什么模式,永远记住,过早的优化是万恶之源(因为一切事物有利就有弊,面向对象带来的问题就是对象过于'丰富',理解起来需要更多的时间),以下的规则适用于大系统,大功能,绝不适用于小功能,写个hello world就别设计模式了,这就是为啥学设计模式感觉不爽,因为例子中的代码太简单了,根本不需要用到设计模式,但是例子又不能太复杂,否则本末倒置了,只能自己在工作中慢慢领悟了,当你感觉代码越来越冗余了,修改越来越麻烦了,这个时候才该考虑是否应该优化重构了

面向对象六大原则

参考: https://www.cnblogs.com/tengpan-cn/p/6504531.html

1、单一职责原则(SRP:Single responsibility principle)

  一个类只负责一种职责,只有这种职责的改变会导致这个类的变更。绕口一点的正统说法:不要存在多于一个原因导致类变更. 假如:类T 负责有两种职责 P1,P2;当P1发生改变时,需要修改类T,这时候可能会对P2造成影响。

  软件工程中的概念 : 判断设计好坏的标准是高内聚低耦合,啥是TM的高内聚,这就是TM的高内聚,高内聚就是说一段代码只负责一个功能,第二个功能让别的代码去负责,不要跟我说这说那,老子TM就只会BB,别的啥也不干,这就是高内聚

  往小点说,每个方法都应该是内聚的,一个方法只干一件事情

  所以不要为了图代码量少,二将不同职责放入到一个类里面。可以写两段代码,再用另一段将这两段组合起来,我只负责A功能,你只负责B功能,他只负责整合我们,没其他卵用.

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

  替换么,啥是替换,我能换成你,就是替换

  比如: 

    A a = new A();  //声明A对象

    B b = new B();  //声明B对象

    a = b ;               //将A对象替换成B对象

  这叫替换.

  这叫鸡儿的替换,连编译都通不过(小声BB).

  所以怎么才能换呢,只有同类才能换,把我换成我?

    A a1 = new A();  //声明A对象

    A a2 = new A();  //声明B对象

    a1 = a2 ;             //将A对象替换成A对象

  这到是编译通过了,但我自己的类型和我自己的类型不能叫替换啊!

   怎么玩呢,就只能有父类才行,这里父类可以是接口,或者类或者抽象类

  比如我们最长见的 List list = new ArrayList();    可以替换为  list = new LinkedList();  

  ArrayList和LinkedList是两个不同的类,但因为都实现了List大接口,所以对于List这个层面来讲,他们是一类,可以替换.

  所以LSP建立在继承/实现的基础上,必须有父子类关系

  里氏替换原则: 只要父类出现的地方,都可以用子类替换,并且不会对程序造成影响.

    如何保证里氏替换原则呢?需要践行下面的规范

  1988年,B. Meyer提出了Design by Contract(契约式设计)理论。DbC从形式化方法中借鉴了一套确保对象行为和自身状态的方法,其基本概念很简单:

  Pre-condition:
  每个方法调用之前,该方法应该校验传入参数的正确性,只有正确才能执行该方法,否则认为调用方违反契约,不予执行。这称为前置条件(Pre-condition)。
  Post-Condition:
  一旦通过前置条件的校验,方法必须执行,并且必须确保执行结果符合契约,这称之为后置条件(Post-condition)。
  Invariant:
  对象本身有一套对自身状态进行校验的检查条件,以确保该对象的本质不发生改变,这称之为不变式(Invariant)。
  以上是单个对象的约束条件。为了满足LSP, 当存在继承关系时,子类中方法的前置条件必须与超类中被覆盖的方法的前置条件相同或者更宽松;而子类中方法的后置条件必须与超类中被覆盖的方法的后置条件相同或者更为严格
  一些OO语言中(比如java)的特性能够说明这一问题:
   继承并且覆盖超类方法的时候,子类中的方法的可见性必须等于或者大于超类中的方法的可见性,子类中的方法所抛出的受检异常只能是超类中对应方法所抛出的受检异常的子类。
  个人认为里氏替换原则可以去看下equals方法,equals是Object类的方法,但是Integer和String等类都重写了父类方法,顺序也是先判断类型是否相同,相同才继续执行比较,不同就直接false,如果我这个例子举得不合适,望告知

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

  百度百科例子很好直接拿来用: https://baike.baidu.com/item/%E4%BE%9D%E8%B5%96%E5%80%92%E7%BD%AE%E5%8E%9F%E5%88%99/6189149?fr=aladdin

  简单讲就是面向接口编程:接口一般是行为的集合,也就是尽可能的对行为抽象。抽象不应该依赖细节,细节应该依赖抽象。

  面对抽象编程,而不是面对具体编程,也就是代码不要上来就写(具体的类/方法),而应该先分析(指定规则/接口方法),有哪些共性啊,如果代码要扩展怎么办?需求变动怎么办?

 

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

  类似单一职责原则,区别是单一职责讲的是代码功能层面的.这个说的是每个接口中的功能尽可能单一.要把一个大接口分成多个,然后通过多实现去组合他们,而不是放在一起.

  接口本质上是两个类之间关系的纽带,关系中不需要有的,在接口中不应该体现。

  如:

    一个A接口中有如下两个方法: 爆粗口(), 文明用语()

    然后有个Person类来实现这个A接口,而这个Person是个文明人,人家不需要 爆粗口() 这个方法,但是没办法,你是子类必须实现,而且如果我把接口中的  爆粗口()  加了参数,或者改了返回值 ,或者改了名字,这个Person都得跟着改,但是人家不用啊,这就造成了不合理

    怎么才能合理呢?

    应该开两个接口  A   只有  爆粗口(),  B 只有 文明用语(),如果一个人是文明人,只需要单一实现B就好了,如果一个人是个正常人经常讲文明,但偶尔爆粗口,可以多实现A,B两个接口,也可以专门有一个人接口C继承A,B两个接口(为了整合),让这个正常人实现C接口即可

5、迪米特法则(Least Knowledge Principle (LKP))

  软件工程中的概念 : 判断设计好坏的标准是高内聚低耦合,啥是TM的低耦合,这就是低耦合.

  耦合可以理解为钟表中紧挨的两个齿轮,一个转动必然带动了另一个转动.正如我们的类,A类和B类,如果A类修改了,使得B无法正常使用了,也必须跟着修改,那就说明这两个类耦合性高,反之,就是低耦合.

  而迪米特法则讲的就是一个对象要对其他对象保持尽可能少的了解,即低耦合性,低耦合可以最大限度的保证代码的可复用性。这个实际上是针对被依赖的类来说的,对于被依赖的类,尽可能的将复杂的逻辑封装起来,对外只提供public方法,外部不需要知道内部的逻辑。

  一开始我理解这个规则的时候,觉得很不可思议,一个类如果和另一个类低耦合了(没关系了),那就是两个单独的类,但凡他们要有点关系就必须耦合在一起,这是个悖论啊,怎么才能达到这样的效果呢?

  因为很多人只说了上面前半句,没说后半句,后半句是这样的 : 迪米特法则不希望类之间建立直接的联系。如果真的有需要建立联系,也希望能通过它的友元类来转达。

  就是说A,B两个齿轮,这样是高耦合,想要解耦,我们引入C齿轮,AB跟C联系,AB之间不能联系,只能通过中介类C发生关系,这样,我们称AB两个类低耦合,但是其实AC和BC就高耦合了,这样也无所谓,因为C只负责联通(符合单一职责),AB各自负责其功能.

  应用迪米特法则有可能造成的一个后果就是:系统中存在大量的中介类,这些类之所以存在完全是为了传递类之间的相互调用关系——这在一定程度上增加了系统的复杂度。

  有兴趣可以研究一下设计模式的门面模式Facade)和中介模式(Mediator),都是迪米特法则应用的例子

  

6、开闭原则(Open-Close Principle(OCP))

  功能应该对扩展开放,对修改关闭。就是想改是不行的,但是你可以通过扩展来达到增加功能,或者修改功能的目的.

  扩展 extends  ,明白这个怎么玩了吧?

  其实就是我这提供的东西你能用就用,不能用自己继承下来重写我的方法,但是别想着改我的源代码,否则测试就需要好大功夫

  举个例子,我们都用Sring框架,我们也看源码,也反编译,有多少人在自己生产环境中改过源代码?不都是继承人家的类,重写人家的方法,用到的时候new自己的对象么

GOF23种设计模式

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

  创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

  创建型模式就是造对象,有的好好的new不用,非xjb造.

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

  结构型模式就是组装组织多个对象,本来一两句代码能解决的问题,非neng一坨类然后互相调用

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

  换个角度看问题,将本来一坨顺序执行(顶死加点循环判断)的像屎一样的代码(但我能用啊),重构到多个类中,以一种更加精干的方式展现在世人面前(但是可能可读性不太好,毕竟代码分的太散了,或者说因为角度不同,需要更大力的去思考去理解)

  但是只有这样,我们才能更好的面向对象,更好的应对需求的修改啊(你看,Spring的功能不满足你的要求,你自己扩展就行,不需要打电话给人家的RD,让人家半夜起来改代码)

    理解设计模式:朋友说了这么一句话:设计模式是一种思想,不要局限于具体的例子(比如有时候你会觉得某个例子既象某个模式,又想另一个模式),有时候例子会误导你的理解,要去看概念,设计模式是为了解决一些特定场景的问题,答案就在概念中,概念会告诉你这个模式解决了什么问题,为什么提出这个模式,了解了这点,就把握住了理解设计模式的根本.

    理解设计模式:面向对象的思想是用来将类关系垂直的构造出来,便于联系,而设计模式是将类关系横向联系,方便扩展

创建型模式

  单例模式:

    这个就不说了,单例省内存,唯一需要注意的就是内部尽量不要使用全局变量,因为线程不安全

  建造者模式:

               百度百科:建造者模式是设计模式的一种,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示(就是创建实例的build可以扩展[传入不同的build创建不同的实例])

    本来能自己new对象,设置数据的,为啥要再来个建造者呢?简单对象确实不用,但是有一些复杂对象可能构造起来比较麻烦,就像我们小时候帮别人拼玩具汽车一样,假如最后的客户需要的是一辆拼好的汽车,他不需要自己去拼,只需要给你所需要的零件就行,你呢,就是那个建造者,帮别人把零件拼起来,作为客户他不需要知道你怎么拼的,过程如何复杂,只需要你说你要车轮,我提供车轮就行,简化客户的操作.

    对于建造者模式,有接口规定每一种零件提供的方法,我们只需要将这个零件类实现好,提供给建造者(diractor),建造者就能给我们返回最后的成品,降低客户端对于最终产品的耦合性

  原型模式(克隆模式):

    百度百科:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

    根据已有对象创建新对象,使用的是Object类的clone方法,这个方法是protected修饰,但是所有对象都继承自Object,所以自己可以重写这个方法,这个方法调用时会检查你的类型是否符合Cloneable,这是一个标记接口,所以让自己的类再实现这个接口,就可以调用clone方法了.

    这里分有浅复制和深复制只说,

    深复制:指的是类中所持有的所有对象是否被复制,如果所有对象都复制了一份就是深复制,也就是旧对象中数据变动不会影响新对象内容

    浅复制:指的是类中引用对象并未被复制,只是新对象持有了引用对象的指针,两个对象持有的是同一个引用,这样旧对象内数据变动,就会影响新对象

    实现深复制,每层的引用对象都重写clone方法,然后在重写的clone方法中显式调用并给新对象赋值即可

  工厂方法模式:

    百度百科:工厂方法模式是一种常用的类创建型设计模式,此模式的核心精神是封装类中变化的部分,提取其中个性化善变的部分为独立类,通过依赖注入以达到解耦、复用和方便后期维护拓展的目的。它的核心结构有四个角色,分别是抽象工厂;具体工厂;抽象产品;具体产品

    首先简单工厂模式不算在GOF23种设计模式中,工厂方法其实就是工厂接口生产产品接口,各自下面又有自己的实现,就是工厂实现生产产品实现

    这样做的好处就是:有接口,那就可扩展,有不同的实现,就可以随意替换,符合开闭和里氏替换原则

  抽象工厂模式:

    百度百科:抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。根据里氏替换原则,任何接受父类型的地方,都应当能够接受子类型。因此,实际上系统所需要的,仅仅是类型与这些抽象产品角色相同的一些实例,而不是这些抽象产品的实例。换言之,也就是这些抽象产品的具体子类的实例。工厂类负责创建抽象产品的具体子类的实例。

    https://blog.csdn.net/u014727260/article/details/82560912

    这个里面讲的非常清楚,感谢博主

    上面的工厂方法一个工厂只生产一类产品,这里我们把产品换个名字,叫零件,也就是工厂生产的这个东西不能作为产品使用

    这里的产品概念是多个零件组成的一个产品,所以我们需要多个上面的工厂,负责生产不同的零件

    零件有了,就得组装成产品,我们这里产品根据不同的零件组成不同的产品,

    而组装多个零件也可以抽象成一个工厂,于是出现了横纵两种坐标,一种用来生产零件,一种用来组合零件为产品

    理解起来可能非常麻烦,但是如果工作中用到其实不至于太难理解

结构型模式

  适配器模式:

    百度百科:配器模式(有时候也称包装样式或者包装)将一个类的接口适配成用户所期待的。一个适配允许通常因为接口不兼容而不能在一起工作的类工作在一起,做法是将类自己的接口包裹在一个已存在的类中。

    适配器就像现实生活中的两插口转成三插口那个工具一样,这个适配器可以讲根本没增加什么新功能,就是一个调用别人方法的中介方法而已.

    当你的方法需要调用a()(一般来说,这个a名字是因为接口规定好了),但是a()这个功能和另一个类的b()一模一样,那么我们可以再写一个类,这个类的实现统一接口,然后在内部a(),调用b(),这样就实现了调用a(),实际执行b()功能,这个新类就是适配器

    其实正常情况下我们自己在a()中调用b(),为啥多创造一个新类呢?就是为了解耦

  装饰器模式:

    菜鸟教程:装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

    一共需要三个类: 一个接口,一个原始类,一个装饰器类

    接口:声明方法

    原始类:实现接口,重写方法

    装饰器类:实现接口,同时在类内部声明一个接口对象,给外界提供一个传入原始对象的入口(可以是set,也可以是构造器,一般是构造器),在重写方法时调用原始对象的方法

    由于装饰器类也实现了接口,所以可以装饰器套装饰器,最内部是原始对象就行

    符合开闭原则,目的是为了扩展功能

  

  代理模式:

    百度百科:所谓的代理者是指一个类别可以作为其它东西的接口。

    一共需要三个类: 一个接口,一个原始类(被代理对象),一个代理对象

    接口:声明方法

    被代理类:实现接口,重写方法

    代理类:实现接口,在类内部持有被代理对象,重写方法时调用被代理对象方法

    为什么要抽出一个代理对象呢,就是说这个被代理类其实完全可以实现全部完整的方法,但是呢,方法中有些代码是通用的,我们希望把这些重复的代码重构一下,所以将这些代码提到代理类中,所以间接的讲,被代理对象的功能其实是不完整的,所以一般客户端不会直接使用被代理类,而是通过代理类去操作.    

 

  装饰器模式和代理模式区别:

    这两种模式写法特别象,只不过一个外壳叫装饰器,一个外壳叫代理对象,既然叫法不同,就说明他们理解角度不同,代理类中是抽出共同方法,装饰器是增加功能(没有代理类功能不完整,没有装饰器功能完整,有了代理类功能正常,有了装饰器,锦上添花)

    装饰器模式在于增加功能,但是整个过程中客户端是知道有原始对象这个东西的,外壳和原始对象的组合方式是使用传参的方式组合在一起的,所以原始对象是客户端new出来的,客户端即使不使用装饰器,直接使用原始对象,功能都是完整的

    代理模式在于补充正常功能,但整个过程中客户端根本没有跟原始对象(被代理对象)产生关系,或者说根本不知道有被代理对象,被代理对象应该是直接new在代理对象中的,客户端只创建代理对象,使用代理对象即可.(但是现实使用过程中,我们可能为了通用,所以没有将代码写死,直接在代理对象中new对象,也是通过传参的方式传入的被代理对象,同时这两种写法都可以是增加功能的作用[人为操作],所以我们会觉得这两个模式特别像),客户端一般的不直接使用被代理对象,因为被代理对象功能不全

    这两种写法都符合开闭原则,不对原始对象内容修改,想要增加功能在外面套壳子就行

      

  外观模式(门面模式):

    菜鸟教程:外观模式(Facade Pattern)隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性。

    slf4j就是典型的外观模式

    外观模式跟上面两种模式最大的特点就是自己没有任何功能,只是为了整合资源,为客户端提供统一的调用方式(就好像天猫淘宝一样,我们称其为平台,他不生产产品,也不负责售卖,只是提供了一个交易平台,简化统一卖家和买家的操作),而且内部持有的对象一定是门户对象自己创建出来的(自己new),对客户端保持透明

    目的是为了解耦,简化操作,方便随意替换内部实现

    slf4j就是这样,我们写法是一样的,具体使用哪个日志实现,其实是slf4j在启动的时候回去扫描整个类目录,查找实现类(log4j)提供的一个入口配置,这个入口配置是约定好的,slf4j声明,log4j实现的,slf4j扫描到就会知道该创建谁了,并且将其初始化,这个过程客户端并不需要知道,只要按着slf4j写法写就行,引用不同的日志实现jar,就可以实现日志无缝切换

  桥接模式:

    百度百科:桥接模式是将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interfce)模式。

    1.一个接口,多个实现,以多态特性实现实现类可以无缝切换的效果(比如使用List声明对象时,arraylist和linkedlist可以无缝切换),此为桥接模式基础(如实现了A功能)

    2.使用A功能,不去继承而是组合,就是持有对方对象,以这种方式调用方法

    此为桥接模式

  组合模式:

    菜鸟教程:组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。

    组合就是类内部持有对方对象,但是这里的组合说的是模式,跟我们平常组装对象又不一样

    组合模式目的为了统一简单对象和复杂对象的处理方式,将复杂对象和简单对象组合到一块(统一处理),网上经常举例文件夹和文件树装结构处理,文件夹就是复杂对象(因为内部还有东西),文件就是简单对象

    理解起来2个要点

    1.统一,想要统一的处理方式,那就得实现相同接口,统一么,对吧,所以简单对象和复杂对象都要实现统一的接口

      这个接口中写统一的方法,方便调用,比如我们声明一个遍历方法,文件夹实现就是进入内部继续递归调用,文件就是直接输出文件名

    2.创建一个组合对象,因为我们分别操纵文件夹或者文件,那就是各是各的,不能叫组合,所以,我们需要这么个对象,来统一操纵简单对象和复杂对象

      这个组合对象中要有一个list集合,里面要能装复杂对象,也要能装简单对象,这样插入删除方法就也能同意了,一个list怎么能装两种类型呢?因为他们都实现了一个接口,这样我们的list的泛型声明成接口类型即可

    到此,我们就组合了2中对象,操纵时将数据先全放到这个组合对象里面,然后通过组合对象的方法,统一处理,但其实内部会各自调用自己重写的父类方法,实现统一调用

  享元模式:

    百度百科:享元模式是一种软件设计模式。它使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件;它适合用于只是因重复而导致使用无法令人接受的大量内存的大量物件。通常物件中的部分状态是可以分享。常见做法是把它们放在外部数据结构,当需要使用时再将它们传递给享元。

    享元模式与单例模式有异曲同工之妙,目的都是为了节省内存,对象只创建一次,之后每次都复用已生成的对象,与单例的区别是,单例中的对象是一个单独的完整的对象,而享元模式中的对象分为内部状态和外部状态两种状态,内外状态组成一个完整的对象,内部状态是共性,创建一次,之后复用,外部状态每次都重新赋值,一对一单独使用

    享元,共享的就是内部状态,外部状态是不共享的,相当于局部单例

    浅复制就类似于是享元的结果,内部共用同一个引用对象

行为型模式

  策略模式: 

      菜鸟教程:在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。

    其实就是if else ,将其中间的处理代码抽出为一个新的类(策略)[开始要声明一个共同的策略接口,统一方法名],在调用时将不同的策略传入即可,为了统一调用,所以在中间还要有一个context上下文,其实就是调用方法的类,类似代理模式(只是类似),这个context就是个代理人,我们不去直接调用策略的方法,而是通过context上下文去调用,实现统一调用

    符合开闭原则,之后新增策略,直接新建一个策略类即可

  模板方法模式:

    菜鸟教程:在模板模式中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式属于行为型模式。

    这个最简单了,根据接口写不同的实现,接口就相当于模板,子类实现就是最后的实现,我们平常写的MVC,ctrl层和service层,dao层,每层的接口和实现都是模板方法

              这个理解有误,多谢朋友犀利指出,这里模板方法大致的样子跟上面一样,但是模板不只是上面这么简单,一般情况下,模板类是一个抽象类,比如:小汽车启动需要点火,给油,这里模板类会将启动方法实现写好,按顺序调用点火,给油方法,而真正的点火给油方法抽象,留给子类实现,这样才是模板模式,比如restTemplat,jdbcTemplat,将模板(重复)方法抽出来,而具体的实现交给子类,抽出的方法才叫模板方法

  观察者模式:

    百度百科:在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。

    在被观察者对象中,维护一个观察者对象的列表,将观察者加入列表称为注册(监听,订阅),移除称为取消订阅.被观察者由于持有观察者列表,所以就可以在必要的时候,可以主动(被观察者主动调用观察者)遍历调用观察者的方法,这步称为通知,我个人理解这种方式类似于回调

  迭代器模式:

    百度百科:迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。

    目的是使遍历和数据相互分开(解耦),所以实现起来就是两个对象,一个遍历数据的对象,一个集合对象本身,将集合对象本身传入遍历对象,就可以调用遍历对象方法来遍历访问集合数据中的每个节点,核心其实还是集合数据本身提供了访问单个数据的方法,再用遍历对象去调用这个方法

    为了规定统一的方法名,所以使用接口定义方法.

  责任链模式:

    百度百科:责任链模式是一种设计模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。

    将处理请求的方法抽象为类,然后组装成一条链,前一个能获取到下一个的对象

    为了调用方便,专有一个类用来自动组合这根链条,然后将请求内容传入这个类,这个类中利用递归来处理这个请求,最后返回结果

  命令模式:

    命令(Command)模式的定义如下:将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理。

    http://c.biancheng.net/view/1380.html

    命令封装为一个对象,其中包括自己的执行方法,但是客户端不直接调用命令对象,还有一个执行者对象,客户端通过调用执行者对象,操纵对应命令对象,所以我们需要将命令传入执行者,执行者还得能调用命令对象方法.

  备忘录模式:

    百度百科:备忘录模式是一种软件设计模式:在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。

              一个对象可能有10个属性,其中有4个属性可能需要随时回滚之前状态,我们可以将这4个属性作为一个状态类,其实到此就可以了,回滚数据时将状态类中的值设置到对象中即可,但是这样两个对象耦合性太高,所以提出另一个对象叫管理对象,将状态对象交给管理对象管理,需要回滚状态时,调用管理对象的方法将状态设置到目标对象中即可

  状态模式:

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

    类似于策略模式,某些类会有一些状态,类会根据当前不同状态做出不同的动作(所以会需要用到if分支),状态模式将状态和动作绑定到一块,抽成一个类,类名就是状态,类中动作即是状态对应的操作,原来是判断状态执行对应动作,现在是获取当前状态,调用状态中的方法.实现状态可扩展

  访问者模式:

    百度百科:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。从定义可以看出结构对象是使用访问者模式必备条件,而且这个结构对象必须存在遍历自身各个对象的方法。这便类似于Java语言当中的collection概念了。

    目的是为了将处理数据的代码和处理的动作分开,

  中介者模式:

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

               平台化,中心化,多个对象之间如果有互相调用关系时,自然会产生耦合,中介者就是为了解决这个问题产生的,所有的对象全部依赖于终结者,这样就能解耦对象之间的联系,客户端只需要跟中介者产生关系就行了

  解释器模式:

               这个不太理解诶...

  未完待续...

转载于:https://www.cnblogs.com/fast-bullet/p/10933832.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值