设计模式摘录

OO基本原则

http://blog.csdn.net/sadfishsc/article/details/7221904

http://blog.csdn.net/zhengzhb/article/details/7278174

1 迭代器模式

通过迭代器遍历聚集对象,聚集对象可以独立于客户端独立演变。迭代器就是客户端和聚集的缓冲地带,吸收了变化。

使得客户端的遍历过程,不受聚集对象变化的影响。迭代模式使得迭代过程抽象化,抽象意味着稳定。

黑箱聚集,不提供外部对其元素的访问接口封装性良好,只能通过内部迭代器暴露访问接口。白箱聚集,可以同时使用内部迭代器和外部迭代器,使用外部迭代器好处是,多个客户端分别使用多个迭代器,不同的迭代器实例保留各自的游标位置,不会相互影响(貌似内部迭代器也可以做到)。迭代过程,聚集发生改变,有快速失败的处理。

2 装饰者模式,也称包装模式。在对客户端透明的情况下,动态的给原有对象添加新行为(而继承是静态添加新行为,编译时刻就决定了)。并且可以通过排列组合的方式,创建丰富行为的对象,比继承灵活很多(要通过继承实现,那得衍生过多的类)。装饰者要和被装饰对象实现同一个接口。多个装饰者层层覆盖就形成一条装饰者链条。

java io系统的装饰者分析:inputStream属于抽象构件(即被装饰者),具体构件有ByteArrayInputStream、FileInputStream、PipedInputstream、StringBufferInputStream。FilterInputStream为抽象装饰者,具体装饰者有DataInputStream、BufferedInputStream、ObjectInputStream等(鉴别的标准在于有没有继承inputStream,并持有一个inputStream的引用,通过构造子初始化)。

3 代理模式,和装饰者、适配器一样都是通过间接引用的方式来降低对象之间的耦合。适配器模式侧重的是改变接口适配调用方,但是完全不改实现;装饰者强调在原有的类的基础上添加新的行为增强功能,并且可以通过多个装饰者层层包装组合出丰富的对象行为,类似链表似的;代理模式不改变接口,让客户感觉不到代理的存在,代理会在执行委托真实操作之前有前置操作和后置操作,代理适用于截获调用,对调用施加控制。

扫描二维码关注公众号,回复: 727828 查看本文章

远程代理hsf,hessian,让用户感觉不大网络的存在。虚拟代理,只有在真正调用时才加载耗资源的模块。保护代理,主要用于做权限检查。智能引用代理,主要用于内务处理,如计数操作

4 责任链模式:责任链是一条处理者链,每个处理者都持有对下家的引用,可以选择自己处理请求或者传递给下家。客户发送请求,不需要知道请求最终由哪个处理者处理。服务端可以动态地调整处理者链,重新分配职责。责任链规定,请求只能被当前处理者处理,或者传给一个下家。责任链可以是线性的,也可以是树,或者图。

5 访问者模式,稳定数据结构,不稳定的操作。对一个聚集不同节点的集合遍历每个节点进行操作。模式的特点是当操作变化时,只需要扩展一个新的访问者,而不需要修改节点代码。也就是说,将对数据结构的操作从数据结构中剥离出来。让操作单独变化。

http://thatax.blog.163.com/blog/static/20892680200881861224834/

http://tech.163.com/05/0718/10/1OUFF2JQ00091589.html

 双重分派,访问者对元素进行的操作取决于访问者和具体元素的组合行为。

6 命令模式。把请求封装为命令,使得请求方和调用方解耦,请求方只负责创建命令,不知道执行命令的细节,调用方负责执行。请求方也不知道调用方何时调用,是否调用。类似回调,c语言中的函数指针。

main方法可以理解为请求方,命令有时候会有个接受者,命令用封装了接收者的接口,统一为Command.execute暴露给Invoker,由invoker来真正触发命令。

命令模式经常用于实现undo,redo;构造请求队列;记录请求日志;事务操作

junit也使用了命令模式,其中junit扮演invoker的角色,我们写的一个具体testcase就是一个command,继承了基类testcase。请求方就是我们,写testcase相当于构建命令,然后让知道如何执行命令的invoker,即junit去执行。

参考:http://wenku.baidu.com/view/0646a4f8941ea76e58fa04ba.html

http://www.51testing.com/html/96/n-130096.html

7 门面模式,门面模式封装了内部子系统,客户只需要和门面打交道,无需了解子系统的细节,使得子系统更容易使用。门面相当于为多个子系统提供了集中化和简单化的调用方式。

门面模式的两个重要角色分别是门面和子系统,子系统不知道门面的存在,门面对于子系统而言只是另外一种客户端;客户端可以通过门面来调用子系统,门面会将请求委派到对应的子系统中,客户端也可以直接调用子系统。

门面的使用场景:

a 为复杂子系统提供简单接口

b 保持子系统的独立性和可移植性,去除子系统之间、子系统和客户端之间的耦合

c 层次化结构,对于层级化的系统,可以为每个层级提供一个简单的门面,层级之间的调用通过门面进行,门面弱化了层级之间的依赖关系。

门面模式是迪米特法则的一个实践,通过门面对象,减少了类与类之间的通信。

一个便于记忆的例子是,一个大房间有10个电灯,不用门面的情况就是,你要打开所有电灯,必须得操作10次开关,如果提供一个统一门面,封装10个电灯的开关,那么你只需要按一个开关即可打开所有。

8 桥梁模式:将抽象化与实现化解耦,使得二者可以独立的变化。桥梁模式的关键在于,在系统中识别出不同范畴的抽象,把庞大的单个层级结构分离成多个层级结构,每个层级结构单独演化。

类图示意

飞机的例子,未使用桥梁模式。可以看出一片混乱,类之间都是用继承关系,直接强耦合。同时两个不同的概念没有分离,在同一个继承结构中。飞机的类型概念,还有飞机的厂商概念(实现方)。



 使用桥梁模式重构后,飞机的概念(抽象化)和飞机的厂商(实现化),分离成两个不同的层级结构,可以单独变化。


jdbc也使用了桥梁模式

jdbc例子


9 享元模式,英文名为flyweight,有轻量级的含义,中文的意思为共享元数据。他可以以共享的方式高效地支持大量细粒度对象。享元对象包含内蕴状态和外蕴状态,内蕴状态在对象创建时即确定;而外蕴状态,根据环境的不同而不同,外蕴状态调用客户端需要自己维护,不同的客户端共享的是享元对象的内蕴状态。

应用场景:

例如编辑器,字母a为内蕴状态,在不同的位置,不同的字体为外蕴状态,他们共享的是a这个字母。jdk中的string也使用了享元模式,值一样的在jvm里面只有一个实例。

类图:



 客户端不直接实例化享元对象,而是通过工厂模式来获得对象,工厂一般为单例;客户端在使用的时候才传入外蕴状态state,外蕴状态作为参数传入operation方法里。operation里面操作的数据对象就是内蕴数据和外蕴数据的结合。

例 sysout("内蕴状态"+intrinsicState+"外蕴状态"+state)。

 上述的为单纯享元模式,除此之外还有一个变种的复合享元模式;即享元模式和组合模式的结合,一个具体享元对象引用了单纯享元对象的聚集,这里面的单纯享元对象是不可复用的。



 

使用场景:

  • 系统有大量的对象
  • 对象耗费大量的内存
  • 对象的大部分状态可以外部化
  • 这些对象可以用内蕴状态分为很多组,当把外蕴状态剔除掉以后,每组可以只用一个对象来代替。
  • 系统不依赖于这些对象的具体身份,换言之是这些对象不可分辨的。

当足够多的对象可以共享时,才值得用享元模式。

享元就是通过共享大量元数据,来实现资源的高复用,系统的轻量化。 

猜你喜欢

转载自hill007299.iteye.com/blog/1434666
今日推荐