在工做初期就看了关于设计模式的书《大话设计模式》简单易懂,可是后来对一些设计模式渐渐模糊,记得最多或者你们说的最多的像单例、工厂记忆深入,如今回头再看一遍,别以一番风味,理解又有不一样,这里我的简单进行记录,其中间杂着我的的一些看法。java
关于例子,你们能够去找这边本看看,或者直接到git上clone一下,地址:https://github.com/PengfeiLiOnGit/designpatterngit
设计模式除了23种外,确定还有衍生出来新的设计模式,可是万武归宗,实则都是对类的抽象。github
面向对象设计模式体现的就是抽象的思想,类是对对象的抽象,抽象类是对类的抽象,接口是对行为的抽象。正则表达式
1、UML 类图:算法
2、原则数据库
单一职责原则:就一个类而言,应该仅有一个引发它变化的缘由。若是一个类承担的职责过多,就等于把这些职责耦合在一块儿,一个职责的变化可能会削弱或者抑制这个类完成其余职责的能力。这种耦合会致使脆弱的设计,当变化发生时,设计会遭受到意想不到的破坏。编程
开放-封闭:软件实体(类、模块、函数)应该是能够扩展,可是不能够修改。面对需求,对程序的改动是经过新代码进行的,而不是更改现有代码。设计模式
依赖倒转原则:抽象不该该依赖细节,细节应该依赖与抽象。(针对接口编程,不要对实现编程)。多线程
高层模块依赖底层模块-这是对的,可是若是是针对实现变成,好比数据库访问依赖某个数据操做,若是一旦更改数据库,意味着高层数据库访问也须要改动,若是把高层和底层都进行抽象化,针对接口变成,那么若是要更改西其余数据库,只须要针对底层访问接口增长新实现就能够,不要改动原有的代码。函数
里氏代换原则:一个软件实体若是使用的是一个父类的话,那么必定适用与其子类,并且它察觉不出父类对象和子类对象的区别。也就是说,在软件里面,把父类都替换成它的子类,程序行为没有变化,简单的说,子类型必须可以替换掉它们的父类型。
迪米特法则:若是两个类没必要彼此直接通讯,那么这两个类就不该当发生直接的相互做用。若是其中一个类须要调用另外一个类的某一个方法的话,可使用第三者转发这个调用。(最少知识原则)
合成/聚合复用原则:尽可能使用合成/聚合,尽可能不要使用类继承。聚合表示弱的“拥有关系”,体现的是A对象能够包涵B对象,但B对象不是A对象的一部分;合成则是一种强的“拥有”关系,体现了严格的部分与总体的关系,同时部分和总体的生命周期同样。
3、设计模式
一、简单工厂:
针对不一样相同的行为可是不一样的算法进行抽象,利用一个简单工厂获取实际的运算类。
二、策略:针对不一样的算法进行封装、让它们之间能够相互替换,此模式让算法的变化不会影响到使用算法的用户。
关键点在于context 经过聚合抽象策略类的引用,请求者只须要知道context的存在就能够了,具体的配置再context进行判断,想比较简单工厂,耦合度再次下降。
固然在context中一样能够再次套用其余模式避免switch分支,好比状态模式等再次进行解耦,或者经过反射。
三、装饰模式:动态的给一个对象添加一些额外的职责,就增长功能来讲,装饰模式比生成子类更加灵活。
关键点在于针对具体的对象,衍生于抽象装饰类,其类继承统一的抽象接口,而且在装饰的实现类中对接口进行实现。在实际调用过程当中,针对实际对象进行调用统一的装饰接口。
而且在抽象装饰类中须要对对象接口进行引用,从而达到装饰,也就添加逻辑的效果。
实际场景中在对某些现有功能须要增长业务的或者功能的时候,增长新的功能实现便可,而不须要修改原有抽象实现,去除原有方法中过多的职责。
四、代理模式:为其余对象提供一种代理以控制对这个对象的访问。
关键点实际对象与代理同时实现相同的接口,同时代理对象保持对实际对象引用。
在实际环境中实际对象中可能会有不少私有逻辑,而请求者只知道代理而不知道实际对象。
五、工厂方法:定义一个用于建立对象的接口,让子类决定实例化哪个类。工厂方法使一个类的实例化延迟到其子类。
相比较简单工厂,工厂模式针对工厂进行抽象,消除了判断与条件分支,若须要扩展实际产品,至须要实现product和creator,而不要修改原有工厂类代码。
六、原型模式:
实际java使用中经过实现cloneAble接口,进行对象的拷贝工做。注意点在于,在实现过程当中须要注意浅拷贝与深拷贝的问题。
七、模版方法模式:模版方法在实际使用过程当中常用,也就是继承的特色决定的。抽象类实现---- 子类重写
八、外观模式:为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更多容易使用。
关键点自在于高层的外观类引用具体的关联对象,实现子系统的功能,并处理具体的任务。
实际场景中组合多个接口,同一在外观类中进行业务处理,最终开放给外部调用者。有点相似于adapter 适配器,可是适配器的思想是针对某个负责的接口同一为一个新的接口,适配器同时是拥有兄弟关系的。
九、建造者模式:将一个复杂的对象的构建与它的表示分离,使得一样的构建过程能够建立不一样的表示。
关键点在于director对象,具体对象构造由它进行实现,虽然经过工厂模式也可实现,经过director 会显示更大的灵活性,在指挥者对象中须要具备build的引用。
实际应用场景,建造抽象过程相同,可是具体的建造细节略有不一样,便可以使用这种设计模式。
十、观察者模式:发布-订阅模式,定义一种一对多的依赖关系,让多个观察者对象同时监听一个主题对象。这个主题对象在状态发生变化的时,会通知全部观察者对象,使它们可以自动更新本身。
十一、抽象工厂模式:提供一个建立一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
基于工厂模式再次对工厂进行抽象,实现的工厂与实现的生产对象再进行对应。抽象工厂比较臃肿,虽然实现了解耦,可是若是须要进行扩展,工做量也会很是之大,相比之下,利用泛型与反射,也已更加简便的实现。
十二、状态模式:当一个对象的内在状态改变时容许改变其行为,这个对象看起来像是改变了其类。
关键点在于context 是state的聚合引用,在实例调用handle处理的时候对state进行判断,并更新context,并更改处理方式。
例如初始化状态为A,A的处理方式若是不知足就设置context中引用的状态为B或C等,根据不一样的状态从而使改变实现的方式,对于须要大量条件判断的状况下尤其适用。
1三、适配器模式:将一个类的接口转换成客户端但愿的另一个接口。解决接口不兼容的问题。
在外观模式中提到,对于已经存在的接口不兼容的状况下进行使用,经过adapter类对原有的接口进行转换。
实际场景,好比使用了第三方的接口,或者其余同事或者原有接口,因为其实现因为各类缘由不能进行修改,因此使用适配器模式,则不须要关注具体实现。
1四、备忘录模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象以外保存这个状态。这样之后就可将该对象回复到原先保存的状态。
做为备忘录的汇集,实际保留备忘录的引用,为何要存在memento而不使用发起者的原型复制,缘由在于再实际过程当中不必定要保存全部信息,可能只是保留一个状态,因此经过memento 实际存储这些信息,
而经过汇集的引用在caretaker中,在须要恢复的时候从其中获取便可。
1五、组合模式:将对象组合成树形结构以标识‘部分-总体’的层次接口。组合模式使得用户对单个对象和组合对象的使用具备一致性。
分支节点与叶子节点同事实现component接口,同时分支节点须要具备对对象接口的汇集引用。
1六、迭代器模式:提供一种方法顺序的访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。
迭代器在实际应用中须要的很少,由于你们面向对象语言中都已经实现了迭代器,迭代器中须要具备下标,与next方法来获取对象,同时根据isDone 来判断是否已经结束。
1七、单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
通常单例对象使用懒加载和DSL 双锁机制,来避免在多线程中生成多个对象。
若是使用饥渴模式的话无需考虑。
public static Singleton getInstance(){ // 在多线程访问的状况下利用DSL 双重锁机制保证明例惟一 // 由于是静态方法,因此使用类锁,或者使用lock 锁,与生成一个对象锁 if(singleton == null){ // 处理业务逻辑 // DSL synchronized (object){ if(singleton==null){ singleton = new Singleton(); } } } return singleton; }
1八、桥接模式:将抽象部分与它的实现部分分离,使它们均可以独立的变化。
实现系统可能有多角度分析,每一种分类都有可能变化,那么就把这种多角度分离出来让它们独立变化,减小它们之间的耦合。
好比手机能够安装品牌区分,同事每一个品牌手机中又拥有类似的功能,可是具体的功能在不一样品牌中实现不一样,那么就可使用桥接模式进行体现。
手机品牌的抽象中聚合手机软件、功能的引用。
利用聚合/复用原则进行弱引用,这样增长品牌或者增长手机功能都不需对原有的代码进行修改,直接扩展便可。
1九、命令模式:将一个请求封装为一个对象,从而使你可用不一样的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操做。
把命令进行抽象,命令的记录与撤销记录在Receiver接收者中,同事在命令中具备最终调用者的引用,下面是书中的截图引用。
20、职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象练成一条链,并沿着这条链传递该请求,知道又一个对象处理它为止。
关键点在于在实现类中须要具备父类的引用,在实现处理请求的时候若是不知足条件,则重置处理实现。
2一、中介模式:用一个中介对象来封装一系列的对象交互。中介者使各对象不须要显示的相互引用,从而使其耦合松散,并且能够独立的改变它们之间的交互。
两个对象进行交互同时经过中介者进行处理,多个对象只与中介对象进行通讯,具体的通讯由中介对象进行处理。
2二、享元模式:运用共享技术有效的支持大量细粒度的对象。
特色对于某一类对象经过共享实例的方式避免内存的过分滥用,同时与单例模式结合,针对须要重复引用的对象共享他们。
建立实例的事物能够交给子类,而后由享元工厂提供接口进行分法。
2三、解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
实际使用场景很少,是一种转换模式,比较出名的例子是正则表达式。
2四、访问者模式:表示一个做用与某对象接口中的各元素的操做。它使你能够在不改变各元素的类的前提下定义做用与这些元素的新操做。
针对特定的对象,进行抽象分类,同时在扩展状态的时候能够很是容易的进行扩展,可是若是要条件ele对象则会形成大量的工做。
此模式针对特定且固定分类的对象比较适用。
例如,男人和女人,可是会有不少中的状态,就比较适合这种设计模式。