java接口与模式(观察者)

1.接口的概念
接口的概念在java中有2种:在人们谈起"接口"的时候,往往指的是一个类所具有的方法的特征集合,是一种逻辑上的抽象。但是在java中,接口的概念还有另外一种,这是一种Java语言存在的结构,有特定的语法和结构。如果你是一个Java开发人员,你是否使用过它呢,你是否了解它呢?我想大部分刚开始工作不久的人,都不会想起原来java中还有这样一个工具去供你驱使。

2.Java接口的特征
Java接口本身没有任何实现,因为它不涉及表象,而只描述public行为,所以它比java抽象类更加抽象化。一个Java接口的方法只能是抽象公开的,它不允许有构造函数。另外,Java接口允许有public static final的属性,也就是所谓的常量。

3.Java接口的功能
接口和类最最主要的区别是,接口仅仅描述方法的特征,而不给出方法的实现,而类不仅给出方法的特征,而且给出方法的实现。接口将方法的特征和方法的实现分离,这种分割,体现在接口常常代表一个角色,它包装与该角色相关的属性和操作。而实现该接口的类便是扮演该角色的演员。一个角色可以由不同的演员来演,而不同演员之间除了扮演的角色相同之外,并不需要有任何的关联和共同之处。这恰恰体现的就是一种可插入性。就像你家里使用的电源插座,假如是个3孔的,那么它可以插电脑,可以插空调,可以插油烟机等等,插座不知道谁会来插它,它只是规范出了使用它的东西必须是3孔的,如果你安装实现的插头是3孔的,那么你就可以使用它。

4.为什么要使用java接口
一个对象需要知道其他的一些对象,并且与其他对象发生相互作用,这是因为这些对象需要借助其他对象的行为来完成一项工作。这些关于其他对象的知识,以及对其他对象的调用,都是使用硬代码写在类里面的,可插入性几乎为0。
一种解决的办法当然是使用继承机制,将父类做成抽象类,不同子类继承然后进行不同的实现,客户端可以动态的决定调用哪个具体子类。这的确可以解决某些时候存在的问题,但是不要忘了java是个单继承的语言,只允许有一个超类,因此,在很多时候,这个类已经有了一个超类,这时候,要想给它再加一个超类,明显不可能了。如果硬要做的话,就只好把这个超类加到已有的超类上面,形成超超类:如果这个位置还是被某个超类占用了,你所抽象的这个超类得继续往上移动,直到最顶端。这样一来,对一个具体类可插入性的设计,就变成了对整个等级结构中所有类的修改。这还是在可控的情况下,理想的情况下发生的。如果这些超类是软件商提供的,设计师无法修改,那怎么办呢?比如一个具体类的超类是Frame,那么新加的抽象超类得一直移动到java.lang.Object类上面,这怎么可能呢?
因此,接口才是可插入性的保证。

5.一个接口使用的例子:观察者模式
一直以来,都想写点东西来回顾下第一年工作做的那个唯一的项目,一直写不出什么,还好,这次终于有了点点感觉。
观察者模式:它定义了一种一对多的依赖关系,让多个观察者对象同时监听某个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己,做自己想做的事。观察者模式最重要的依据就是状态,状态发生变化时,通知某个对象进行操作。如果你的系统里面有类似的功能,那么可以考虑使用它。
观察者模式具有如下四个角色:抽象主题,具体主题,抽象观察者,具体观察者。
那个项目中的应用场景是这样的:项目是个手机客户端,需要联网从服务器端获取数据,然后解析在客户端显示。使用过手机上网的人应该会很清楚,在你按下键确定联网时,屏幕上会出现一个联网进度条,进行一些联网的信息提示,以便让用户耐心等待,结果是联网失败给出错误提示,或者是成功刷新页面内容。
这中间大致有下面3个对象:
1.客户端页面对象:主要进行页面的绘制 Page
2.数据处理对象:解析从服务器返回的数据或者封装要post到服务端的数据 DataHandler
3.http对象:发送http请求:get或者post,连接服务器发送或者获取所需数据。HttpUtil
那个时候,我们项目中大概有40多个页面,一个http连接的工具类,还没有数据处理对象。最开始的设计是,各自页面直接包装http请求,通过http工具类与服务端进行交互。这样直接的做法带来一个极其严重的问题,每个页面得写很多重复的代码:例如http请求的封装与发送,是否需要联网的判断,联网过程的进度条信息,联网失败后的提示,或者成功后的数据解析,在每个页面类中不断重复。显然,这不是个好设计,最后很自然想到了在中间加上一个数据处理类,这显然是一个抽象超类,用来封装每个页面与服务器交互都需要出现的代码。而每个页面差异的地方,就由继承的各自子类--PageDataHandler去实现。
对象抽象完毕后,剩余的就是功能的实现了。仔细观察这个应用,很显然,它完全符合观察者模式的定义。在这里:Page观察DataHandler,DataHandler观察HttpUtil。
为了满足可插入性,定义了2个接口类:HandlerObserver,HttpObserver,分别是DataHandler与HttpUtil的观察者。每个Page实现HandlerObserver,而每个PageDataHandler持有对应Page的HandlerObserver对象的引用,同理DataHandler实现了HttpObserver,HttpUtil持有所有请求所带的HttpObserver的引用。这样当Page要发送请求时,只需要将实现好的HandlerObserver对象以及一些必要的信息传递给与之相对应的类PageDataHandler即可,同理PageDataHandler也只需要父类DataHandler中的方法将父类实现的HttpObserver对象传递给HttpUtil即可。这样HttpUtil类就可以在各种状态下,通过持有的观察者对象的引用,回调所对应的方法。
我们把它戏称为双重观察者模式。

如果你有心注意,你会发现接口的使用是极其的普遍的,几乎所有控件的事件驱动都采用的单方法接口。赶紧拿起这把武器去武装你的代码与思路吧。

原文地址:https://www.cnblogs.com/komojoemary/p/2255877.html