观察者模式——定义了对象之间的一对多关系,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
何时使用:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。
关键代码:在抽象类中有一个ArrayList存放观察者们
注意事项:
1、JAVA中已经有了观察者模式的支持类
2、避免循环引用
3、如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。
代码实现观察者模式(“推”方式):
1、观察者接口
public interface Observer {
void update(String msg);
}
观察者1
public class FirstObserver implements Observer {
@Override
public void update(String msg) {
System.out.println("FirstObserver get msg : " + msg);
}
}
观察者2
public class SecondObserver implements Observer {
@Override
public void update(String msg) {
System.out.println("SecondObserver get msg : " + msg);
}
}
2、被观察者接口
public interface Observable {
//注册新观察者
public void registerObserver(Observer observer);
//删除观察者
public void removeObserver(Observer observer);
//通知所有观察者
public void notifyObservers();
}
被观察者
public class Subject implements Observable{
private String msg;
private List<Observer> observerList = new ArrayList<>();
public void setMsg(String msg) {
this.msg = msg;
}
@Override
public void registerObserver(Observer observer) {
observerList.add(observer);
}
@Override
public void removeObserver(Observer observer) {
int i = observerList.indexOf(observer);
observerList.remove(i);
}
@Override
public void notifyObservers() {
for(Observer observer : observerList) {
observer.update(msg);
}
}
}
3、测试
public class Run {
public static void main(String[] args) {
Subject s = new Subject();
s.setMsg("Hello World!");
FirstObserver firstObserver = new FirstObserver();
SecondObserver secondObserver = new SecondObserver();
s.registerObserver(firstObserver);
s.registerObserver(secondObserver);
s.notifyObservers();
}
}
输出:
FirstObserver get msg : Hello World!
SecondObserver get msg : Hello World!
利用JAVA内置的观察者模式实现(“拉”方式)
1、观察者
实现java.util.Observer接口
public class FirstObserver implements Observer {
private String msg;
@Override
public void update(Observable o, Object arg) {
if(o instanceof Subject) {
Subject subject = (Subject) o;
this.msg = subject.getMsg();
display();
}
}
public void display() {
System.out.println("FirstObserver get msg : " + msg);
}
}
public class SecondObserver implements Observer {
private String msg;
@Override
public void update(Observable o, Object arg) {
if(o instanceof Subject) {
Subject subject = (Subject) o;
//从被观察者“拉”取自身需要的数据
this.msg = subject.getMsg();
display();
}
}
public void display() {
System.out.println("SecondObserver get msg : " + msg);
}
}
2、被观察者
继承import java.util.Observable类,在通知所有观察者前必须setChanged()表示状态已改变,这样保证在更新观察者时有更大的弹性。
public class Subject extends Observable {
private String msg;
public void statusChanged() {
setChanged();
notifyObservers();
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getMsg() {
return msg;
}
}
3、测试
public class Run {
public static void main(String[] args) {
Subject s = new Subject();
s.setMsg("Hello World!");
FirstObserver firstObserver = new FirstObserver();
SecondObserver secondObserver = new SecondObserver();
s.addObserver(firstObserver);
s.addObserver(secondObserver);
s.statusChanged();
}
}
输出
输出次序与上面的不同,这是由于notifyObservers()的实现方式不同。
SecondObserver get msg : Hello World!
FirstObserver get msg : Hello World!
注意:
1、Observable是一个类,这限制了复用的潜力。
2、Observable将关键方法保护了起来,setChanged()被定义为protected。这意味着除非集成Observable,否则无法创建Observable实例并组合到自己的对象中来。这违反了第二个设计原则“多用组合,少用继承”。
网友评论