您的位置:首页 > 其它

设计模式学习笔记十一:观察者模式

2015-07-27 08:54 661 查看

设计模式学习笔记十一:观察者模式

介绍

观察者(observer)模式也叫发布-订阅模式,实现了观察者和被观察者的解耦操作,观察者可以根据自身需求选择关注哪些主题和取消关注哪些主题,当主题发生变化的时候会轮询通知观察者,所以主题和观察者之间是一对多的关系。

典型应用

MQ

AWT事件监听

NIO多路复用

……

UML结构图:



代码实现:

1.主题接口

package com.array7.observer;

public interface Subject<T> {
/**
* 创建观察者
* @param observer
*/
public void add(Observer<T> observer);

/**
* 删除观察者
* @param observer
*/
public void remove(Observer<T> observer);

/**
* 轮询通知观察或者
*/
public void notifyObservers();
}


2.具体主题实现

package com.array7.observer;

import java.util.HashSet;
import java.util.Set;

/**
* 具体的主题,即被观察者
*/
public class ConcrectSubject implements Subject<String> {
private Set<Observer<String>> observers;

private String changeData;

public ConcrectSubject() {
observers = new HashSet<Observer<String>>();
}

@Override
public void add(Observer<String> observer) {
observers.add(observer);
}

@Override
public void remove(Observer<String> observer) {
observers.remove(observer);
}

@Override
public void notifyObservers() {
for (Observer<String> observer : observers) {
observer.update(this.getChangeData());
}
}

public String getChangeData() {
return changeData;
}

/**
* 触发update操作的方法
*/
public void setChangeData(String changeData) {
this.changeData = changeData;
notifyObservers();
}

}


3.观察者接口

package com.array7.observer;

/**
* 观察者接口
* @param <T>
*/
public interface Observer<T> {
/**
* 状态更新通知
* @param t
*/
public void update(T t);

/**
* 主题已经存在了一个remove(..)方法,依然可以提供一个取消订阅的方法(可选)
* 为了区分这里名称定义为了quit()
*/
public void quit();
}


4.具体观察者实现

package com.array7.observer;

/**
* 具体的观察者
*/
public class ConcrectObserver implements Observer<String>, BizService<String> {
private Subject<String> subject;

public ConcrectObserver(Subject<String> subject) {
subject.add(this);
this.subject = subject;
}

@Override
public void update(String str) {
// logic
dosmth(str);
}

@Override
public void dosmth(String str) {
System.out.println(Thread.currentThread().getName() + ":" + str);
}

@Override
public void quit() {
subject.remove(this);
}
}


5.其他业务逻辑组合

package com.array7.observer;
/**
* 强制在观察者具体实现类实现此方法
*/
public interface BizService<T> {
public void dosmth(T t);
}


6.Run

package com.array7.observer;

/**
* 运行类
*/
public class Run {
public static void main(String[] args) {
ConcrectSubject subject = new ConcrectSubject();
// 初始化一个观察者
new ConcrectObserver(subject);
subject.setChangeData("abcd");
subject.setChangeData("1234");

ConcrectObserver tmpObserver = new ConcrectObserver(subject);
subject.setChangeData("dcba");
// 删除这个观察者
subject.remove(tmpObserver);

// 新加入的观察者,我们预计会输出两次4321 :]
new ConcrectObserver(subject);
subject.setChangeData("4321");
}
}


TIPS

在JDK中也提供的观察者模式的实现,但是JDK中的观察者接口是使用抽象类实现的。这就意味着如果想使用JDK中自带的实现,就不能再继承其他的基类了。而如果在基类继承,代码耦合度又会上来,因为可能不是所有的类都需要使用观察者。能用接口,尽量不用继承,也是设计原则之一:多用组合,少用继承
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: