设计模式 —— 观察者模式

观察者(Observer)模式:

  观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。

  观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

 下面以一个简单的示意性实现为例,讨论观察者模式的结构。

观察者模式

 

观察者模式所涉及的角色有:

●  抽象主题(Subject)角色:抽象主题角色把所有对观察者对象的引用保存在一个聚集(比如ArrayList对象)里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象,抽象主题角色又叫做抽象被观察者(Observable)角色。

●  具体主题(ConcreteSubject)角色:将有关状态存入具体观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色又叫做具体被观察者(Concrete Observable)角色。

●  抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在得到主题的通知时更新自己,这个接口叫做更新接口。

●  具体观察者(ConcreteObserver)角色:存储与主题的状态自恰的状态。具体观察者角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态 像协调。如果需要,具体观察者角色可以保持一个指向具体主题对象的引用。

案例:

星际争霸中,重工厂的附件可以升级坦克支架。如果有多个重工厂附件时,其中一个升级了坦克支架那么其他几个附件中,坦克支架图片就会消失并且不能升级。

 

 

 

 

 

设计模式 —— 中介者模式

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

     通过定义我们可以看出中介者主要是通过中介对象来封装对象之间的关系,使之各个对象在不需要知道其他对象的具体信息情况下通过中介者对象来与之通信。同时通过引用中介者对象来减少系统对象之间关系,提高了对象的可复用和系统的可扩展性。

     但是就是因为中介者对象封装了对象之间的关联关系,导致中介者对象变得比较庞大,所承担的责任也比较多。它需要知道每个对象和他们之间的交互细节,如果它出问题,将会导致整个系统都会出问题。所以它比较容易应用也很容易误用。故当系统中出现了“多对多”交互复杂的关系群时,千万别急着使用中介者模式,你首先需要做的就是反思你的系统在设计上是不是合理。

下图是中介者模式的UML结构图:

2222

      它主要包含如下几个角色:

        Mediator: 抽象中介者。定义了同事对象到中介者对象之间的接口。

        ConcreteMediator: 具体中介者。实现抽象中介者的方法,它需要知道所有的具体同事类,同时需要从具体的同事类那里接收信息,并且向具体的同事类发送信息。

        Colleague: 抽象同事类。

        ConcreteColleague: 具体同事类。每个具体同事类都只需要知道自己的行为即可,但是他们都需要认识中介者。

在中介者模式中中介者对象处于核心地位,因为它定义了整个系统中所有具体同事类之间的关系。在整个系统中它主要承担两个方面的责任。

      1、 结构上起到中转作用。通过中介者对象对关系的封装,使得具体的同事类不再需要显示的引用其他对象,它只需要通过中介者就可以完成与其他同事类之间的通信。

      2、 行为上起到协作作用。中介者对同事类之间的关系进行封装,同事类在不需要知道其他对象的情况下通过中介者与其他对象完成通信。在这个过程中同事类是不需要指明中介者该如何做,中介者可以根据自身的逻辑来进行协调,对同事的请求进一步处理,将同事成员之间的关系行为进行分离和封装。

      同时由于中介者对对象的关系进行了封装,使得各个同事类之间的耦合减少了,使得他们可以独立改变和复用。

 

案例:

房东与租客通过房屋中介进行联系。

 

具体调用

 

参考链接:

http://www.cnblogs.com/chenssy/p/3348520.html

设计模式 —— 迭代器模式

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

迭代器模式由以下角色组成:

迭代器角色(Iterator):迭代器角色负责定义访问和遍历元素的接口。

具体迭代器角色(Concrete Iterator):具体迭代器角色要实现迭代器接口,并要记录遍历中的当前位置。

容器角色(Container):容器角色负责提供创建具体迭代器角色的接口。

具体容器角色(Concrete Container):具体容器角色实现创建具体迭代器角色的接口。这个具体迭代器角色与该容器的结构相关。

迭代器设计模式结构如如下:

具体如下:

 

设计模式 —— 解释器模式

解释器模式(Interpreter),给定一个语言,定义它的文法的一种表示,并定义一个解释器,用这个解释器使用该表示来解释语言中句子。解释器模式需要解决的是,如果一种特定类型的问题发生的频率足够高,那么可能就值得。

在开篇之前还是要科普几个概念:
抽象语法树
解释器模式并未解释如何创建一个抽象语法树。它不涉及语法分析。抽象语法树可用一个表驱动的语法分析程序来完成,也可用手写的(通常为递归下降法)语法分析程序创建,或直接client提供。

解析器
指的是把描述客户端调用要求的表达式,经过解析,形成一个抽象语法树的程序。

解释器
指的是解释抽象语法树,并执行每个节点对应的功能的程序。

要使用解释器模式,一个重要的前提就是要定义一套语法规则,也称为文法。不管这套文法的规则是简单还是复杂,必须要有这些规则,因为解释器模式就是按照这些规则来进行解析并执行相应的功能的。

enter image description here

案例:

一个计算器。(目前只能加减/或者乘除,并且必须按照一定格式)

接口,让子类必须存在此方法

主要用于存放数字的类

符号抽象类。定义规则,存在符号左侧变量及右侧变量。

一下是加减乘除操作类

计算器类,用户解析表达式,并进行计算。

调用计算

 

一个比简单粗俗的计算器完成。

参考链接:

http://www.cnblogs.com/chenssy/p/3346427.html

http://www.html-js.com/article/2085

设计模式 —— 工厂模式

工厂方法模式(Factory Method),定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。说的通俗一点吧,就是把将工厂类抽象成接口,具体的代工厂去实现此接口,同时把产品类也抽象成接口,再构造具体的产品去实现些接口。

 

案例:

创建不同类型的灯泡

 

工厂模式与建造者模式的类似。但是还是有一些区别的。

  1. 建造模式侧重于“装配”、“拼装”…而工厂侧重于“生产”
  2. 建造模式的导演,很清楚产生的步骤,因为他把握这生产者的接口(知道生产步骤)而工厂,却不知道,他只知道自己产出产品
  3. 建造模式屏蔽的是“装配”的细节,工厂模式则是屏蔽“构造”的细节…(有点晕其实)

建造模式,适用的范围是:

1)当产品对象非常复杂,无法一步到位生产,需要有N个部件拼合才能成行,但是步骤是固定的(重点),不过部件的属性可能不一样(内部表象不一样)

2)产品里面的需要填充的属性,比较难取得,需要另外的生产者进行生产才行,概括起来说就是,建造模式是当产品比较复杂(不能一下子完成),而且生产步骤已经稳定,但是同一个步骤 产出的“部件”可能属性不一样!这时候使用建造者模式最好

 

另一个角度说,建造模式比工厂模式“宏观”,建造模式里面的生产者可以是工厂模式!

CSS3 —— animation 之 steps方式过渡

测试连接

参考:

http://www.gbtags.com/gb/share/3213.htm

设计模式 —— 外观模式

Facade外观模式,是一种结构型模式,它主要解决的问题是:组件的客户和组件中各种复杂的子系统有了过多的耦合,随着外部客户程序和各子系统的演化,这种过多的耦合面临很多变化的挑战。

GoF《设计模式》中说道:为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

缺点就是,外观模式违反了开闭原则。

案例:

公司的web站点,每晚都要将其库存信息传递至公司内的不同系统。不过它是一个比较老的系统,并且只能处理大写的字符串。

具体操作: CD 对象 -> 属性转大写 -> 传输XML。

创建实例

 

普通调用,如果需求更对那么每次调用的时候都需要写N多行代码。如下:

外观模式,把上面代码封装起来,其他地方调用时候只需一行代码即可。如下:

 

设计模式 —— 委托模式

委托模式是软件设计模式中的一项基本技巧。在委托模式中,有两个对象参与处理同一个请求,接受请求的对象将请求委托给另一个对象来处理。委托模式是一项基本技巧,许多其他的模式,如状态模式、策略模式、访问者模式本质上是在更特殊的场合采用了委托模式。委托模式使得我们可以用聚合来替代继承,它还使我们可以模拟mixin。

 

案例:

MP3文件播放列表,访问者可以选择下载M3U或者PLS格式的播放列表。

添加歌曲,通过用户的命令下载播放列表。

如果说播放列表的格式越来越多了,那么if…else…更多了,那样很不美观和代码冗余。

我们可以委托者模式类解决这个问题。

Playlist是委托者,然后有m3u和pls等的被委托者。

playlist委托者存在一个私有变量存放被委托者,然后我们可以调用被委托者的方法,让用户下载其所要的格式。

调用如下,代码就是如此清晰简洁。

 

设计模式 —— 装饰模式

Decorator装饰模式是一种结构型模式,它主要是解决:“过度地使用了继承来扩展对象的功能”,由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性;并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀(多继承)。继承为类型引入的静态特质的意思是说以继承的方式使某一类型要获得功能是在编译时。所谓静态,是指在编译时;动态,是指在运行时。

GoF《设计模式》中说道:动态的给一个对象添加一些额外的职责。就增加功能而言,Decorator模式比生成子类更为灵活。

案例:

有2款手机nokia和moto。有基本的打电话和发短信功能。

使用装饰模式可以为其随意的添加功能。

增加功能只需实例化一个功能类,并将目标类传入即可。

 

设计模式 —— 建造者模式

建造者模式

将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。

Builder模式 主要用于“分步骤构建一个复杂的对象”。在这其中“分步骤”是一个稳定的乘法,而复杂对象的各个部分则经常变化。

Builder模式主要在于应对“复杂对象各个部分”的频繁需求变动。其缺点在于难以应对“分步骤构建算法”的需求变动。

案例:

设置房子基本框架,有门、窗、墙、地板等。

假设我们需要造不同风格的房子。需要为其设置不同的属性。如下:

这样的代码,很不美观,写起来也很麻烦。

那么建造者模式的用处就来了。

设置一个建造者抽象类。

如果我们需要中国风格的房子我们就继承它,并设置中国风格房子的属性。如下:

我们也可以需要日本风格的房子,如下:

最后使用起来,简单又美观。