introduction:
观察者模式:
Subjet+Observer = 观察者模式
定义对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
一个有状态的主题对应多个观察者。
主题是正真拥有数据的人,观察者是主题的依赖者。
这样的设计可以使对象之间松耦合,他们之间相互交互,但是不清楚彼此之间的细节。
观察者模式允许推和拉两种模式。
java内置的观察者模式,包含observer接口和observable类,可以使用push(推)或拉(pull)的方式传送数据。
observable违法oo设计原则,因为observable是一个类,java不支持多重继承,这样就限制了observable的复用潜力。
有多个观察者时,不可以依赖特定的通知次序。
demo:使用自定义的观察者模式,模拟web 容器的状态,web容器的状态可以被每一次请求订阅,web容器可以将状态放回给请求
Subject.java
public interface Subject {
void addObserver(Observer o);
void deleteObserver(Observer o);
void notifyObserver();
}
Observer.java
public interface Observer {
void update(Event event);
void print();
}
Event.java
public class Event {
private Integer status;
public Event(){}
public Event(Integer status){
this.status = status;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
@Override
public String toString() {
if(status == 1){
return "container status: open";
}
if(status == 0){
return "container status: close";
}
return "container status: refresh";
}
}
Container.java
public class Container implements Subject{
private Event event;
private List<Observer> observers = new ArrayList<Observer>();
@Override
public void addObserver(Observer o) {
observers.add(o);
}
@Override
public void deleteObserver(Observer o) {
int i = observers.indexOf(o);
if(i>=0){
observers.remove(i);
}
}
@Override
public void notifyObserver() {
for(int i=0;i<observers.size();i++){
observers.get(i).update(event);
}
}
public void setEvent(Event event){
this.event = event;
setEventChange();
}
public void setEventChange(){
notifyObserver();
}
}
Request.java
public class Request implements Observer{
private Subject subject;
private Event event;
public Request(Subject subject){
this.subject = subject;
if(subject instanceof Container){
subject.addObserver(this);
}
}
@Override
public void update(Event event) {
this.event = event;
print();
}
@Override
public void print() {
System.out.println(event);
}
}
Test.java
public class Test {
public static void main(String[] args) {
Container subject = new Container();
Observer observer = new Request(subject);
subject.setEvent(new Event(1));
subject.setEvent(new Event(0));
subject.setEvent(new Event(-1));
subject.setEvent(new Event(22));
}
}
输出结果:
container status: open
container status: close
container status: refresh
container status: refresh