设计模式之观察者模式(Observer)
其实我以前也有学习过设计模式,也写过一些代码。这次在看代码时,发现设计模式使用的泛滥,想想我的设计模式学习的不够扎实,所以重新拾起,把以前没有学习的设计模式学习一遍,把学习过的设计模式在重温一遍。第一篇我选择的是观察者模式。我在项目代码中看到这个模式,项目中的使用大概说一下:服务器与客户端的交互,服务器端的代码使用了观察者模式,作用是:当用户发送请求以后,通过注册的Manager管理类来调用相应的方法处理用户的请求。
这里做一个报社新闻给用户推送新闻的案例(当报社推送新闻的时候,所有订阅了报社的读者可以阅读报纸):
方案一:采用Java自带的观察者接口实现,如下:
首先是报社类,继承了Observable,需要注意的是在通知观察者之前需要setChanged一下,因为notifyObservers()在调用时,需要知道自己的观察者发生了改变,而这个方法是通过Changed变量来判断是否为true,如果不为true,直接return,具体可以查看源码。所以我们需要setChanged,让hasChanged方法返回true。具体可以看notifyObservers()的定义说明
import java.util.Observable;
public class Publisher extends Observable {
public void updateNews(String str) {
setChanged();
notifyObservers(str);
}
}
然后是用户读者:(这里做了2个读者)需要实现Observer接口,并实现接口内部的具体方法update().实现这样的update方法,主要是因为在notifyObservers函数中对这个update方法进行了调用。这也是设计模式的精髓所在。我们可以查看Observable的具体实现,从而知道如何设计一个抽象的观察者。
import java.util.Observable;
import java.util.Observer;
public class Reader_1 implements Observer{
@Override
public void update(Observable o, Object arg) {
// TODO Auto-generated method stub
if(arg instanceof String){
System.out.println("I'm Reader_1,"+(String)arg);
}
}
}
import java.util.Observable;
import java.util.Observer;
public class Reader_2 implements Observer{
@Override
public void update(Observable o, Object arg) {
// TODO Auto-generated method stub
if(arg instanceof String){
System.out.println("I'm Reader_2,"+(String)arg);
}
}
}
然后是我们的测试Main类:需要做的是创建出版社,读者1,读者2。
读者1,读者2都订阅报社的报纸。第一次推送。
然后读者1退订报纸,报社第二次推送。
public class Main {
public static void main(String[] args) {
Publisher p = new Publisher();
Reader_1 r1 = new Reader_1();
Reader_2 r2 = new Reader_2();
p.addObserver(r1);
p.addObserver(r2);
System.out.println("当前读者数:"+p.countObservers());
System.out.println("第一次推送消息:");
p.updateNews("CCTV-5 SportNews");
p.deleteObserver(r1);
System.out.println("\n当前读者数:"+p.countObservers());
System.out.println("第二次推送消息:");
p.updateNews("News for Car");
}
}
运行结果:
当前读者数:2 第一次推送消息: I'm Reader_2,CCTV-5 SportNews I'm Reader_1,CCTV-5 SportNews 当前读者数:1 第二次推送消息: I'm Reader_2,News for Car
==============================================================================================================================
方案二:自己动手,丰衣足食。我们需要实现的是抽象报社,抽象读者,具体报社,具体读者,外加一个测试函数即可,
其实跟Java自己实现的观察者接口相差并不多,下面就简单的实现它的基础功能,如下所示:
思路清晰,写代码:
package demo;
import java.util.Vector;
public class AbstractPublisher {
// 库函数采用的是Vector来实现对注册读者的存储,我们也走大神的路
Vector<AbstractReader> vector;
public AbstractPublisher() {
vector = new Vector<AbstractReader>();
}
public boolean addReader(AbstractReader ar) {
if (vector.add(ar))
return true;
return false;
}
public boolean deleteReader(AbstractReader ar) {
if (vector.remove(ar))
return true;
return false;
}
public void notifyReaders(String news) {
for (AbstractReader ar : vector) {
ar.readNews(news);
}
}
}
package demo;
public interface AbstractReader {
public void readNews(String news);
}
package demo;
public class Publisher extends AbstractPublisher {
//推送新闻给读者
public void pushNews(String news) {
notifyReaders(news);
}
}
package demo;
public class Reader_Joy implements AbstractReader{
@Override
public void readNews(String news) {
// TODO Auto-generated method stub
System.out.println("I'm Reader_Joy " + news);
}
}
package demo;
public class Reader_Tom implements AbstractReader{
@Override
public void readNews(String news) {
// TODO Auto-generated method stub
System.out.println("I'm Reader_Tom "+news);
}
}
package demo;
public class Main {
public static void main(String[] args) {
Publisher p = new Publisher();
Reader_Joy joy = new Reader_Joy();
Reader_Tom tom = new Reader_Tom();
p.addReader(joy);
p.addReader(tom);
System.out.println("第一次推送消息:");
p.pushNews("News Of Game");
p.deleteReader(joy);
System.out.println("第二次推送消息:");
p.pushNews("News Of City");
}
}
运行结果:
第一次推送消息: I'm Reader_Joy News Of Game I'm Reader_Tom News Of Game 第二次推送消息: I'm Reader_Tom News Of City
基本的代码实现就是这样,也许还有错误,但是观察者的基本思想就此理清楚了。
核心部分:1)报社如何存储注册的读者
2)报社如何通知注册的读者
3)如何使用接口和继承的方式组织结构。
项目源代码:http://www.kuaipan.cn/file/id_132802506211221411.htm?source=1

浙公网安备 33010602011771号