您的位置:首页 > 编程语言 > Java开发

java设计模式(3)观察者模式

2017-03-11 12:15 239 查看
观察者模式是行为型模式的一种,该模式的主要有2种角色:观察者和被观察者。可以把被观察者当做一个“主题”,一旦这个主题有更新,订阅该主题的观察者就能收到消息。因此,观察者模式又被称为“发布-订阅”模式。

举个更通俗的例子,某类报纸比如《人民日报》和它的订阅者们。一旦有了新一期的《人民日报》,报社就会主动把报纸送到订阅者手上。

那让我们想想看,上述情景抽象到代码里要怎样实现呢?首先,报社不能见个人就送报纸,也不能遗漏哪个订阅者。所以最简单的方式是,报社那有一份订阅者的名单,而且,如果有人不想订了或有新的订阅者,也要能处理。

报社类

/**
* 报社类
*/
public class NewsPaper {

//订阅者名单
private List<Observer> observers = new ArrayList<>(0);

//添加订阅者
public void addObserver(Observer observer) {
observers.add(observer);
}

//移除订阅者
public void removeObserver(Observer observer) {
observers.remove(observer);

}
}


订阅者类暂时先不管,报纸类有了订阅者名单还不行,主要是能把报纸送出去,添加一个送报纸的方法。

//NewsPaper类 通知订阅者,比拟送报纸
public void notifyObservers(){
//遍历订阅者,发送消息
for(Observer observer:observers){
//模拟通知,送报纸操作
}
}


到现在我们要考虑订阅者类了,订阅者需要有一个接受消息的方法(收报纸)。

public interface Observer {
//消息来后处理方法
void update(String msg);
}


观察者类就类似上述这样。是个接口?对。我们会有许多观察者,而且这些观察者当消息来后处理的方式不会都一致。具体处理方式交给实现类解决。

这样的话,我们的新闻类的通知方式应该是这样:

//通知订阅者
public void notifyObservers(){
for(Observer observer:observers){
observer.update("有新报纸了");
}
}


实现一个订阅者接口,真正处理消息。

public class ObserverImpl implements Observer {

private String name;

public ObserverImpl(String name) {
this.name = name;
}
public void update(String msg) {
System.out.println(name+"阅读消息:" + msg);
}
}


好了,到现在我们的逻辑是,报社有一份订阅者名单,有新报纸后逐一通知订阅者。订阅者不需要时时去报社问有没有新报纸,只需在家等着即可。

为了更好的解耦,一般的观察者模式中,主题(也就是例中的报社)一般也采用接口化的设计。

主题类:

//主题类
public interface Subject {
void addObserver(Observer observer);

void removeObserver(Observer observer);

void notifyObservers(String msg);
}


主题的具体实现类

public class NewsPaper implements Subject{

//订阅者名单
private List<Observer> observers = new ArrayList<>(0);

//添加订阅者
@Override
public void addObserver(Observer observer) {
observers.add(observer);
}

//移除订阅者
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);

}

//通知观察者
@Override
public void notifyObservers(String msg) {
for(Observer observer:observers){
observer.update("有新报纸了");
}
}
}


现在我们来测试一下

public class TestObserver {

@Test
public void test(){
Observer observer1 = new ObserverImpl("观察者1");
Observer observer2 = new ObserverImpl("观察者2");
Subject subject = new NewsPaper();
subject.addObserver(observer1);
subject.addObserver(observer2);
subject.notifyObservers("我消息更新了");
}
}


输出:

观察者1阅读消息:有新报纸了

观察者2阅读消息:有新报纸了

如果有在消息收到后需要有其他操作,重新实现
Subject
类即可。

————全文完————————-
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息