设计模式的三个大类:
创建型模式:是对类的是实例化过程的抽象化 , 描述了如何构造和封装这些动态的决定。
结构型模式:描述如何将类或者对象结合在一起形成更大的结构。
行为模式:是对在不同的对象之间划分责任和算法的抽象化,行为模式不仅仅是关于类和对象的,而且是关于他们之间的相互作用的。
用一个类对各种交互进行进行封装,就是中介者模式,体现了OOP的封装思想。
设计模式的总体思考:
设计模式无非是利用
1.类与类之间的横向和纵向关系,包括(依赖,关联,聚合,组合,继承,实现),耦合度依次增强。
2.然后再加上各种不同应用场景和逻辑环境(类里方法逻辑不同),一种特定设计模式解决了一类环境下程序设计问题
3.综合1和2的变化--->才产生了N种设计模式。(如果只考虑1的话,设计模式就仅仅几种)
代码重构的原则:
1.对继承的等级结构进行重构时,应当尽量:将行为尽量移动到结构的高端,而将状态尽量移动到结构的低端。
1. 接口是可插入性的保证,理解:如果一个关联不是针对一个具体类的,而是针对一个接口的,那么任何实现这个接口
2.依赖倒转原则的强调: 要针对抽象和接口去编程,不要针对具体编程。的类就都可以满足要求了,理解插排可插入很多电器,就是这个意思,进而实现了抽象,多态。
3. Is-A应该用继承的纵向关系,has-A用横向的聚合关系。
4.里氏代换的本质,一个软件实体如果使用的是一个基类的话,那么一定适用于其子类,而且它根本不能察觉出基类对象和子类对象的区别。
也就是说,尽量不要在子类中重写父类方法,尽量在子类中去扩展新的方法,才能保持这种继承结构,满足里氏代换原则。
5.依赖倒转原则: 理解可以推出结论,离氏带环原则是依赖倒转原则的基础。
6.接口隔离原则: 定制接口和服务,本质上就是为统一个角色提供宽窄不同的接口,以对付不同的客户端
适配器模式的应用。按角色得分割接口,不能所有的接口不管逻辑,都放到一个类中,这肯定是有问题的。
7.一个模块设计的好的标志:可以把它所有的实现细节隐藏起来,彻底地将提供给外界的API和自己的实现分隔开来。
so:模块模块之间可以仅仅通过彼此的API相互通信,而不用理会模块内部的工作细节。本质: 体现了 封装性--->软件设计的基本原则之一。好处: 可彻底的使各个模块之间脱耦合,允许模块独立的被开发使用、优化。
8.尽量降低一个类的访问权限+尽量降低成员的访问权限一旦某一个模块是性能瓶颈时,设计人员可以针对这个模块本身进行优化,而不必担心影响到其他模块。
ps:在满足需求的情况下,应该尽量降低这个类的访问权限。-->如果类成员为public肯定比private危险,
以为一旦public的东西改变,则可能影响客户端, 如果改为private,只可能影响内部。
9.简单工厂在java中的经典应用就是 Dateformat类,根据传入的字符串格式,进行Date类的格式化。
这就解释了为什么那么多类起名字叫factory类。 封装具体实例化类或对象的过程。
public static final String getDateStr(Date aDate) {if (aDate == null) {return "";}SimpleDateFormat df = new SimpleDateFormat(datePattern);return df.format(aDate);}
10. 在具体编程中,(客户端)变成逻辑用的都是接口和抽象类,而不是具体的类,这就是针对接口编程(依赖倒转原则)。
11.
12.抽象工厂: 本质就是当产品有多个逻辑种类时,用抽象工厂模式,
例子:
13.单例模式: windows的垃圾回收站就是典型的应用。
14.建造者本质的思想: 就是把复杂对象的构建过程封装起来,像构建个小人,建胳膊,建脑袋。。等等构建四肢过程,
封装在一个导演类当中的construct函数中,client调用这个导演类的建造方法完成建造过程,不会出现构建少步骤的问题。
15.原始模型模式:就是clone模式, java语言中,就用java.lang.Object的clone函数即可实现,
但是此函数实现的是浅复制,即只clone此对象及其变量,但是对其持有的引用,并不复制引用的对象。对于深复制,即用串行化解决,java.io.serializable接收实现. Page 351
16.java串行化: 本质,就是可以使一个程序可以把一个完整的对象写到一个byte流里面,
或者从一个Byte流里面读出一个事先储存在里面的完整对象;
串行化使得java对象和原始数据类型可以在网络或文件系统中传输。
17.缺省适配模式:本质:就是加一个抽象类可以使具体子类免于被迫实现空的方法
原理:.正常的话,一个类实现一个接口就要实现这个接口规定的所有方法,即使是空实现,也要有这个方法。
但是缺省适配,就是在两者中间,加一个abstract类去实现这个接口,abstract类中所有方法都空实现即可
最后此类继承这个abstract类,即可实现,只实现自己想实现的方法,其他方法不用添加。
好处: 当一个类用不到接口中的N多方法时,如果只是简单实现接口,不用方法也添加,只是不实现,这样的传统方法,
可能会造成代码的冗余,阅读起来很困难,不优雅的代码。
18.几乎所有的应用程序都有一些系统常亮需要存储在程序外部,可以用xml或propertys等配置文件保存。
便于修改,一旦参数变化,也不用去动程序,程序更模块化,本质应该是一个逻辑集,分离数据。
19.组合模式,合成模式,整体-部分模式,一样,本质上:-->为了解决整体与部分的关系而设计的!
解决的问题: 以树形逻辑的业务逻辑,用此模式可完全表示这逻辑。
此模式完美的把部分和整体的关系用树结构表达出来,并且使得整体和部分可以被一致对待分类: 分为安全方式的组合模式,和非安全方式的树形模式。
组合模式终于理解了!
20.装饰模式, 就是组合模式的基础上,对树枝节点再进行抽象化,下面再继承各种装饰子类。
本质上:就是动态给对象增加一些额外的职责(属性和方法),比继承的方式(生成子类)更加的灵活
----适配器模式例子:经典
----第27章 讲 java I/O方面解释的很精辟 java 设计模式 太牛逼了
---桥接模式: 充分体现了合成/聚合服用原则。 将抽象化(手机品牌)和实现化(手机软件)分离,也就是脱耦,使得二者可以独立变化。
---类之间关系无非两种,一种是继承关系,一种是聚合/合成关系,显然两者比较,第二种更加灵活,如果两者都可以使用
那么优先使用第二种方式, 因为第一种方式本身就是将父类与子类绑定,形成了一种强耦合方式。
这就是所谓的聚合/合成复用原则。
桥梁模式--->突出了聚合/合成复用原则。
----不变模式:就是对象初始化后,其状态不可改变。
java String类用到了不变模式和享元模式!
Long类 Integer类等都是包裹类,里面的值不能变,都没有提供修改内部值的方法,因此叫不变模式。
----模板方法模式: 一个抽象超类给出结构的顶级行为,而由一个或者多个具体子类具体实现顶级行为的细节步骤。
子类可以很容易的置换掉超类的方法,而不需要继承超类的状态。
规范: 以do开头的方法,在模板方法模式中,标志着这个方法留给子类实现。
-----职责链模式: 看到UML图实质上跟组合模式的UML图结构是一致的,唯一是类的方法有点差别。
再次印证了一个道理, 设计模式基于类与类之间的结构--->但是更是针对具体应用环境设计的!!
-----状态模式理解; UML设计图和策略模式一样,区别在于:
1.策略模式没有明显的状态和状态的过度,策略模式时,环境角色只用或只有一种状态。
2.策略模式一般自己选择一个策略类;而状态模式的环境类是被外在原因放进一个具体状态中。
策略模式所选的策略往往并不明显地告诉客户端它所选择的具体策略;
而状态模式则相反,在状态模式里面,环境角色所处的状态是明显告诉给客户端的。
pS:就是策略模式和责任链模式的结合。