前言:
相信每一个开发者都希望自己的代码是结构清晰,复用性强,可扩展性佳的。而好的开发者也都是需要做到这一点的,观察者模式是一个非常经典的模式,此次的分享就是这个模式。
关于设计原则与设计模式的关系,可以用道与术的说法来进行区分:设计原则就相当于道,是代码编写当中的核心思想,是针对于写出易读、易复用、易扩展的代码而归纳总结的通用性的编码原则;而设计模式更接近与术,就是在符合设计原则的基础上,对于具体的代码场景提出的模板性的编码方法。在设计模式的学习当中,如果仅仅学习设计原则,很容易泛泛而谈,显得空洞,而如果仅仅学习设计模式,又会学得过于死板,失去了代码编写过程中核心的设计思想。因此,以后的分享当中,会以具体的设计模式为基础,穿插设计原则,与大家一起讨论如何编写优秀而高效的代码。
24种设计模式:
总的来说24种设计模式可以分为三大类
创建型模式,共六种:工厂方法模式、抽象工厂模式、简单工厂模式、单例模式、建造者模式、原型模式。
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
6大设计原则:
单一责任原则:每个类的作用应当单一
开闭原则:对拓展开放,对修改关闭
接口隔离原则:每个接口的功能应当单一
里氏替换原则(父子替换原则):所有引用父类对象的地方都可以透明的改为引用子类对象
依赖倒置原则(面向接口原则):抽象不应该依赖于细节,细节应当依赖于抽象
狄米特原则(最少知识原则):尽量减少类与类之间的相互调用,只与直接相关的对象通信
一、综述:
定义: 观察者模式,又可以称为“主题(Subject)---观察者(Oberver)”模式,是一种一对多的关系,是一种用于多个观察者获取同一主题中的信息的有效方式。
思想: 观察者模式的主要实现思路是让主题拥有多个观察者的实例,然后当主题变化时,由主题来主动将信息传递给观察者,不需要观察者不断地向主题询问状态。
优势: 观察者模式的优势在于结构清晰,信息的通信方式变得单一,减轻了观察者的负担,同时也有利于观察者的拓展。
实现: 观察者模式通常包含四个部分,抽象主题,实现主题,抽象观察者,实现观察者。
抽象主题:主题的抽象基类,包含观察者的列表、以及定义了注册观察者、注销观察者、通知观察者的接口。
实现主题:继承于抽象主题,并实现一些具体主题可能的信息传输的函数
抽象观察者:观察者的抽象类,update方法被主题的notify调用来通知自身观察的主题得到更新
实现观察者:观察者的实现类,实现了基类的接口,并可以加入一些其他的方法
其UML类图如图1:
图1:观察者模式UML类图
二、实例
1、实例一---美女小红:
这里以一个具体的生活中的事件来对观察者模式进行一个比较直观的讲解,同时也祝大家的爱情之路一帆风顺,终成正果。
小红是一个大美女,追求者众多,不过小红有一个正在闹分手的男友,追求者们都在等着机会对小红展开攻势。然而追求者想要知道小红的信息,所幸小红有一个愿意向广大追求者们提供小红信息的室友小丽,于是追求者们就向小丽询问小红的信息。然而追求者们天天来问小丽,小丽觉得很烦。于是小丽告诉他们,来我这里登记,一旦小红分手,她会一一通知追求者,于是追求者们就跑去做自己的事情,小丽也轻松了很多。等着等着有一个追求者名叫小强由于时间的流逝,不再想追求小红了,于是找到了小丽告诉小丽小红如果分手了就不用再告诉他了,于是小丽就把追求者小强的名字从名单上划去,不再通知他。终于有一天,小红分手了,小丽按着名单一个一个的通知每一个追求者,追求者接到通知之后,按照自己的战略战术向着小红展开了攻势。
这个故事比较形象地对观察者的运用进行了说明,其中,小丽就是观察者模式中的主题(Subject),追求者们就是观察者(Observer),这里的事件(onChanged)就是小红的分手。追求者们(observer)向小红进行登记的过程就是注册观察者(Observer)到主题(Subject)的列表(List<Observer>)的过程,小强向小红取消登记的过程就是注销观察者(unRegister)的过程。小红分手事件发生(onChanged)后,小丽通知追求者们这一事件(notify)的动作就是主题告知观察者们事件更新,追求者们按照自己的方法展开攻势(update)的就是得到更新动作后的观察者的具体实现。
2、实例二---Android的按钮控件的响应过程
经过第一个实例,相信大家对于观察者模式已经有了一定的了解,接下来就基于android当中的按钮点击的响应过程来进行对于观察者模式的第二次实例解析。
我们常用的软件都是有界面的,而界面当中,最常见的一个控件就是按钮,按钮实现了一个非常基础的功能,就是点击。而我们的程序就是通过用户的点击事件来进行响应,此处就以android的Button控件的按钮响应过程来对观察者模式来进行一个简单的讲解。
Android当中,按钮的使用方法是这样的:
Button button = (Button)findViewById(R.id.button);
button.setOnclickListener(new OnClickListener(){
public void onClick(View v){
//do some response
}
});
按钮事件的响应过程是一个标准的观察者模式的实现,这里进行简单的说明,对于源码这里不贴出来,有兴趣的可以下来问我,调用的过程非常简单,Button是View的子类,View当中有一个成员变量为ListenerInfo,其中就包含了监听点击事件的OnClickListener,然后将OnClickListener成员变量设置为这里新建的OnClickListener对象。
可以看到,这里的Button就相当于一个主题,Button被点击的动作就是事件,Button当中的OnClickListener对象就相当于观察者,setOnClickListener的过程就相当于对主题进行注册的过程,而OnClickListener当中的onClick方法就相当于观察者中的update()方法。不过这里的Button当中存储的不是一个OnClickListener的数组,而是一个单独的OnClickListener对象,所以这里的观察者数量只会有1和0两种情况。
三、总结
设计模式在编程当中有着十分重要的角色,能够为我们写出漂亮的代码提供良好的模板,那么观察者模式主要体现了哪些设计原则呢?首先,良好的设计模式必然是符合多种设计原则的,不过不同的设计模式对于设计原则的体现各有不同,观察者模式的主要思想体现在:开闭原则,方便于观察者的扩展,对于主题的修改是关闭的;面向接口原则,主题永远调用了子类的update方法而不关心子类的具体实现。