当对象间存在一对多关系时,则适合使用观察者模式(Observer Pattern)。当一个对象的装态被改变时,则应该通知它的观察者对象,这就是观察者模式。
二、代码实现被观察者类
public class Subject {
private int status;
private List observers = new ArrayList<>();
public void attach(Observer observer) {
this.observers.add(observer);
}
public void notifyAllObservers() {
for (Observer observer : observers) {
observer.update();
}
}
public void setStatus(int status) {
//状态变化
this.status = status;
System.out.println("状态改变!");
//通知观察者
this.notifyAllObservers();
}
}
观察者抽象类
public abstract class Observer {
protected Subject subject;
public abstract void update();
}
观察者类
public class SubjectObserver extends Observer {
public SubjectObserver(Subject subject) {
this.subject = subject;
this.subject.attach(this);
}
@Override
public void update() {
System.out.println("被观察者对象subject状态发生变化!");
}
}
测试demo
public class Test {
public static void main(String[] args) {
Subject subject = new Subject();
SubjectObserver observer = new SubjectObserver(subject);
subject.setStatus(1);
}
}
运行结果
生产者与消费者的关系在我们日常生活中非常的普遍,一家超市算是产品池(数据池),我们大众会去消费购买产品,属于消费者,当产品余量不足时会通知供货商发送新的产品过来,供货商就类似于生产者(当然这中间可能有中间商赚差价),一个生产与消费的关系边构建起来了。参考观察者模式,可以给数据池两个身份的观察者,一个是生产者,一个是消费者,代码如下:
数据池
public class DataPool{ private BlockingQueue dataPool ; private final int MAX_SIZE; //生产者 private DataPoolObserver producer; //消费者 private DataPoolObserver consumer; public DataPool(int MAX_SIZE) { this.dataPool = new ArrayBlockingQueue<>(MAX_SIZE); this.MAX_SIZE = MAX_SIZE; } public void setProducer(DataPoolObserver producer) { this.producer = producer; } public void setConsumer(DataPoolObserver consumer) { this.consumer = consumer; } public void add(T t) { this.dataPool.add(t); if (this.consumer != null) { this.consumer.update(); } } public T get() { //余量不足,通知生产者 if (this.dataPool.size() < 0.2 * this.MAX_SIZE && this.producer != null) { this.producer.update(); } if (this.dataPool.size() > 0) { return this.dataPool.poll(); } return null; } }
观察者抽象类
public abstract class DataPoolObserver{ protected DataPool dataPool; public abstract void update(); }
生产者类
public class Producer extends DataPoolObserver{ public Producer(DataPool dataPool) { this.dataPool = dataPool; this.dataPool.setProducer(this); } public void run() { System.out.println("生产了一个产品!"); this.dataPool.add("产品"); } @Override public void update() { this.run(); } }
消费者类
public class Consumer extends DataPoolObserver{ public Consumer(DataPool dataPool) { this.dataPool = dataPool; this.dataPool.setConsumer(this); } public void run() { System.out.println("消费了一个产品!"); this.dataPool.get(); } @Override public void update() { run(); } }
测试类
public class Test {
public static void main(String[] args) {
DataPool dataPool = new DataPool<>(20);
Producer producer = new Producer(dataPool);
observerPattern.Consumer consumer = new observerPattern.Consumer(dataPool);
producer.run();
}
}
运行结果
这样就实现了一个生产与消费的关系,如果生产者和消费者都实现Runnable接口,就可以使用线程实现异步的生产和消费关系,更加灵活。这样的设计可以给数据传输处理提供便利。



