观察者模式
观察者模式是一种对象行为模式。它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。在观察者模式中,主题是通知的发布者,它发出通知时并不需要知道谁是它的观察者,可以有任意数目的观察者订阅并接收通知。
观察者模式的主要的作用就是对对象解耦,将观察者和被观察者完全隔离。
优点
观察者模式解除了主题和具体观察者的耦合,让耦合的双方都依赖于抽象,而不是依赖具体。
缺点
在应用观察者模式时需要考虑一下开发小路问题,程序中包括一个被观察者和多个被观察者,开发和调试比较复杂,而且Java中的消息的通知默认是顺序执行的,一个观察者的卡顿会影响整体的执行效率。在这种情况下,一般考虑采用异步的方式。
下面的例子是以图书出版社与图书销售代理机构的关系,出版社作为被观察者,多家代理商作为观察者,uml类图如下:
代码实现:
public interface Publisher {
public void advanceNotice();
public void officialRelease();
}
public interface Observable {
public void addObserver(Observer observer);
public void deleteObserver(Observer observer);
public void notifyAllObserver(String context);
}
public class BookPublisher implements Publisher, Observable {
ArrayList<Observer> bookAgents = new ArrayList();
@Override
public void addObserver(Observer observer) {
bookAgents.add(observer);
}
@Override
public void deleteObserver(Observer observer) {
bookAgents.remove(observer);
}
@Override
public void notifyAllObserver(String context) {
for(Observer o:bookAgents){
o.update(context);
}
}
@Override
public void advanceNotice() {
this.notifyAllObserver("A即将出版的图书有:《乔布斯传》《穷查理宝典》《聪明的投资者》--xx出版社");
}
@Override
public void officialRelease() {
this.notifyAllObserver("O现已出版的图书有:《HBO的内容战略》《与运气竞争》《稀缺》--xx出版社");
}
}
public interface Agent {
public void sellNotice(String context);
public void sell(String context);
}
public interface Observer {
public void update(String context);
}
public class Agent1 implements Observer, Agent {
@Override
public void sellNotice(String context) {
System.out.println(context);
}
@Override
public void sell(String context) {
System.out.println(context);
}
@Override
public void update(String context) {
if(context.startsWith("A")){
this.sellNotice(context.substring(1, context.length())+"Agent1");
}
if(context.startsWith("O")){
this.sell(context.substring(1, context.length())+ "Agent1");
}
}
}
public class Agent2 implements Observer, Agent {
@Override
public void sellNotice(String context) {
System.out.println(context);
}
@Override
public void sell(String context) {
System.out.println(context);
}
@Override
public void update(String context) {
if(context.startsWith("A")){
this.sellNotice(context.substring(1, context.length())+ "Agent2");
}
if(context.startsWith("O")){
this.sell(context.substring(1, context.length())+ "Agent2");
}
}
}
public class Agent3 implements Observer, Agent {
@Override
public void sellNotice(String context) {
System.out.println(context);
}
@Override
public void sell(String context) {
System.out.println(context);
}
@Override
public void update(String context) {
if(context.startsWith("A")){
this.sellNotice(context.substring(1, context.length())+ "Agent3");
}
if(context.startsWith("O")){
this.sell(context.substring(1, context.length())+ "Agent3");
}
}
}
public class Client {
public static void main(String[] args) {
BookPublisher bp = new BookPublisher();
Observer agent1 = new Agent1();
Observer agent2 = new Agent2();
Observer agent3 = new Agent3();
bp.addObserver(agent1);
bp.addObserver(agent2);
bp.addObserver(agent3);
bp.advanceNotice();
bp.officialRelease();
}
}