二十、观察者模式
观察者模式(observer pattern )用于对象间存在一对多关系时。一个修改对象,可以通知其他依赖对象及时更新。
简介
观察者模式,主要考虑到一个对象的改变通知其他依赖对象,而且要考虑易用和低耦合。
- 优点:观察者和被观察者是抽象耦合的,建立一套触发机制。
- 缺点:若被观察者有很多观察者的话,那么通知起来比较费劲。若观察与被观察之间还有循环依赖的话,可能导致啊系统的循环调用,甚至崩溃。
观察者只能知道有变化,而不知道怎么变化的。
实现
观察者使用三个类Subject、Observer、Client。Subject对象嗲有绑定观察者的方法。需要创建Subject类、Observer抽象类和它的继承实现类。
- 创建Subject类
import java.util.ArrayList;
import java.util.List;
/**
* Created by lenovo on 2016/12/1 0001.
* subject 类,包含绑定观察者和通知观察者的方法
*/
public class Subject {
private List<Observer> observers = new ArrayList<>();
private int state;
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
notifyAllObservers();
}
/**
* 通知更新所有observer
*/
private void notifyAllObservers() {
for (Observer ob : observers) {
ob.update();
}
}
/**
* 绑定observer观察者
* @param observer
*/
public void attach(Observer observer){
observers.add(observer);
}
}
- 创建抽象观察者类
/**
* Created by lenovo on 2016/12/1 0001.
* 抽象的observer观察这类
*/
public abstract class Observer {
protected Subject subject;
public abstract void update();
}
- 创建实体类
BinaryObserver.java
/**
* Created by lenovo on 2016/12/1 0001.
* 观察者实体类
*/
public class BinaryObserver extends Observer {
public BinaryObserver(Subject subject) {
this.subject = subject;
this.subject.attach(this);
}
/**
* 更新状态
*/
@Override
public void update() {
System.out.println("Binary String : " + Integer.toBinaryString(subject.getState()));
}
}
OctalObserver.java
/**
* Created by lenovo on 2016/12/1 0001.
* 观察者实体类
*/
public class OctalObserver extends Observer{
public OctalObserver(Subject subject){
this.subject = subject;
this.subject.attach(this);
}
/**
* 更新状态
*/
@Override
public void update() {
System.out.println("Octal String : " + Integer.toOctalString(subject.getState()));
}
}
HexaObserver.java
/**
* Created by lenovo on 2016/12/1 0001.
* 观察者实体类
*/
public class HexaObserver extends Observer {
public HexaObserver(Subject subject) {
this.subject = subject;
this.subject.attach(this);
}
/**
* 更新状态
*/
@Override
public void update() {
System.out.println("Hexa String : " + Integer.toHexString(subject.getState()).toUpperCase());
}
}
- 演示
ObserverPatternDemo.java
/**
* Created by lenovo on 2016/12/1 0001.
* 使用subject和实体类观察者
*/
public class ObserverPatternDemo {
public static void main(String[] args){
Subject subject = new Subject();
new HexaObserver(subject);
new OctalObserver(subject);
new BinaryObserver(subject);
System.out.println("第一次状态改变:state = 15");
subject.setState(15);
System.out.println("第二次状态改变:state = 20");
subject.setState(20);
}
}
- 输出
第一次状态改变:state = 15
Hexa String : F
Octal String : 17
Binary String : 1111
第二次状态改变:state = 20
Hexa String : 14
Octal String : 24
Binary String : 10100