设计模式之观察者模式

来源:互联网 发布:数据挖掘外文书籍推荐 编辑:程序博客网 时间:2024/05/16 12:52

GOF对观察者模式的定义是:观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态发生改变时,会通知所有的观察者对象,让他们自动更新自己。先来看基本代码。

/** *  * @author ricardo * @Time 下午9:31:55 * @Function:抽象的观察者模式 * */public abstract class Observer {public abstract void Update();}
public class ConcreteObserver extends Observer {private String observerName;private String State;//主题private ConcreteSubject concreteSubject;public ConcreteObserver(ConcreteSubject concreteSubject,String ovserverName) {this.concreteSubject = concreteSubject;this.observerName = ovserverName;}public ConcreteSubject getConcreteSubject() {return concreteSubject;}public void setConcreteSubject(ConcreteSubject concreteSubject) {this.concreteSubject = concreteSubject;}//获取情报@Overridepublic void Update() {State = concreteSubject.getStrate();System.out.println(observerName + "观察到状态是:" + State);}}
/** *  * @author ricardo * @Time 下午3:18:07 * @Function:抽象通知者 * */public abstract class Subject {private ArrayList<Observer> observers = new ArrayList<Observer>();public void Attach(Observer observer) {observers.add(observer);}public void Detach(Observer observer) {observers.remove(observer);}public void Notify() {for(int i = 0;i<observers.size();i++) {observers.get(i).Update();}}}
public class ConcreteSubject extends Subject{private String Strate;public String getStrate() {return Strate;}public void setStrate(String strate) {Strate = strate;}}
客户端代码

public class Client {public static void main(String[] args) {ConcreteSubject concreteSubject = new ConcreteSubject();concreteSubject.Attach(new ConcreteObserver(concreteSubject, "一号观测者"));concreteSubject.Attach(new ConcreteObserver(concreteSubject, "二号观测者"));concreteSubject.Attach(new ConcreteObserver(concreteSubject, "三号观测者"));concreteSubject.setStrate("fLYING");concreteSubject.Notify();}}
运行截图:



来看个具体的案例,乙丙两个国家要获取甲国的资料,于是使用了间谍来操作

/** *  * @author ricardo * @Time 下午9:35:24 * @Function:国家类 * */public abstract class Country {protected String countryName;protected Spy spy;public Country(String countryName, Spy spy) {super();this.countryName = countryName;this.spy = spy;}public abstract void Update();}public class CountryA extends Country {public CountryA(String countryName, Spy spy) {super(countryName,spy);}@Overridepublic void Update() {// TODO Auto-generated method stubSystem.out.println(countryName + "得到"+spy.spyName+"的情报"+ spy.getIntelligence()+"决定与甲国开战");}}public class CountryB extends Country {public CountryB(String countryName, Spy spy) {super(countryName, spy);}@Overridepublic void Update() {// TODO Auto-generated method stubSystem.out.println(countryName + "得到"+spy.spyName+"的情报\"+ spy.getIntelligence()+\"决定与甲国建交");}}
看间谍的相关类

import java.util.ArrayList;/** *  * @author ricardo * @Time 下午3:29:08 * @Function:抽象间谍类 * */public abstract class Spy {private ArrayList<Country> countries = new ArrayList<Country>();private String intelligence;//情报public String spyName;public void Attach(Country country) {countries.add(country);}public void Detach(Country country) {countries.remove(country);}public void Notify() {for(int i = 0;i<countries.size();i++) {countries.get(i).Update();}}public String getIntelligence() {return intelligence;}public void setIntelligence(String intelligence) {this.intelligence = intelligence;}}public class Spy007 extends Spy {public Spy007() {spyName = "007";}}
客户端代码

public class Client {public static void main(String[] args) {Spy  spy007 = new Spy007();Country countryA = new CountryA("乙国",spy007);Country countryB = new CountryA("丙国",spy007);spy007.Attach(countryA);spy007.Attach(countryB);spy007.setIntelligence("甲国制作了核武器");spy007.Notify();}}
运行截图



再看一个在银行大厅办理业务的情况

import java.util.Vector;public class BankBix {public static void main(String[] args) {Counter counter = new Counter("1号柜台");//1,2号显示屏SmallScreen screen1 = new SmallScreen("1号显示屏", counter);SmallScreen screen2 = new SmallScreen("2号显示屏", counter);//加入通知显示屏counter.attach(screen1);counter.attach(screen2);//10号办理业务counter.setBizNo("10");//显示屏更新counter.notifyChange();}}/** *  * @author ricardo * @Time 下午7:46:31 * @Function:银行柜台 * */class Counter{//显示屏列表private Vector<SmallScreen> vectSmallScreen = new Vector<SmallScreen>();//当前业务号private String bizNo;//柜台名称private String name;public Counter(String name) {super();this.name = name;}//增加一个显示屏public void attach(SmallScreen screen) {vectSmallScreen.add(screen);}//去除一个显示屏public void detach(SmallScreen screen) {vectSmallScreen.remove(screen);}//通知显示屏显示public void notifyChange() {for(int i=0;i<vectSmallScreen.size();i++) {SmallScreen screen = vectSmallScreen.get(i);screen.display();}}//获取当前业务号public String getSubject() {return "请" + this.bizNo + "号到" + this.name + "号柜台办理业务";}public String getBizNo() {return bizNo;}public void setBizNo(String bizNo) {this.bizNo = bizNo;}}class SmallScreen{private String name;private Counter counter;public SmallScreen(String name, Counter counter) {super();this.name = name;this.counter = counter;}public void display() {System.out.println(this.name + ":" + counter.getSubject());}}
来看截图

当一个系统被分割成一系列相互协作的类的时候,会有一个副作用,那就是必须维护与之相关的对象之间的一致性。儿观察者模式是解决这一问题的良好的解决方案,一个被观察者可以由任意数目的依赖于他的观察者,当观察者的状态发生改变时,所有观察者都会收到通知,而被观察者在发出通知时也不需要知道是谁在观察自己,同时每一个观察者也不知道其他观察者的存在。

总而言之,使用观察者的最终结果就是解除耦合,让互相耦合的双方都依赖于抽象而不是具体。这样一来任何一方发生改变都不会影响到另一方。

以上内容,整理自刘径舟,张玉华编著的《设计模式其实很简单》读书笔记,欢迎转载




原创粉丝点击