大话设计模式之观察者模式

来源:互联网 发布:包头广电网络活动 编辑:程序博客网 时间:2024/05/16 12:29

不知道大家有没有听说过观察者模式,有人也叫发布-订阅模式,我们先来看一个案例,案例如下:一个公司有前台人员,和后台开发人员,公司老板回来的时候会先经过前台然后才来到后台开发这边,工作压力大,后台开发人员偶尔会偷偷懒,炒一下股或者看看NBA这些小工作,他们串通前台的人员,如果老板回来要先通知他们,好让他们有个准备。程序实现如下:

第一步:我们把前台人员称为通知者,我们抽象通知者,因为通知者可能是前台人员或者其他人,但是具有相同的行为,于是可以使用接口来规范行为。

//抽象通知者public interface Subject {//添加public void attach(Observer observer);//通知所有的观察者public void notifyAllObserver();}
第二步:前台人员是具体的通知者,实现接口Subject,有三个私有属性,姓名,自己的状态,以及需要通知的观察者,我们把后台开发人员称为观察者,他们可能在看NBA,或者看篮球等等。当老板回来的时候,通知者需要改变自己的状态,通知所有的观察者对象,当然通知者肯定有添加观察者的方法,就是添加需要通知的观察者,这里有两个具体的通知者,一个是前台人员,一个是老板,我们都不希望是老板来通知我们~~
import java.util.ArrayList;import java.util.Iterator;import java.util.List;//抽象通知者public class Secretary implements Subject {private String name;  //姓名private String action; //状态private List<Observer> observers = new ArrayList<Observer>(); //观察者集合//添加public void attach(Observer observer) {observers.add(observer);}//通知所有的观察者public void notifyAllObserver() {for (Iterator<Observer> iter=observers.iterator(); iter.hasNext();) {Observer observer = iter.next();observer.update();}}public String getAction() {return action;}public void setAction(String action) {this.action = action;}public String getName() {return name;}public void setName(String name) {this.name = name;}}
import java.util.ArrayList;import java.util.Iterator;import java.util.List;//通知者public class Boss implements Subject{private String name;  //姓名private String action; //状态private List<Observer> observers = new ArrayList<Observer>(); //观察者集合//添加public void attach(Observer observer) {observers.add(observer);}//通知所有的观察者public void notifyAllObserver() {for (Iterator<Observer> iter=observers.iterator(); iter.hasNext();) {Observer observer = iter.next();observer.update();}}public String getAction() {return action;}public void setAction(String action) {this.action = action;}public String getName() {return name;}public void setName(String name) {this.name = name;}}
第三步:抽象观察者,因为我们知道观察者有各种各样的,在做什么事情,我们都不知道,但是老板回来,我们就需要通知他们。
于是我使用抽象类来定义,而不使用接口,因为抽象类可以有属性,即是状态数据字段,定义一个抽象的方法,就是更新自己的状态,也有一个通知者的引用,进而和通知者联系。
//抽象观察者public abstract class Observer {protected String name;  //姓名protected Secretary secretary; //通知者//constructorpublic Observer(String name, Secretary secretary) {this.name = name;this.secretary = secretary;}//更新状态public abstract void update();}
第四步:我们来两个具体的观察者,一个在看NBA,一个在炒股。

//NBA观察者public class NBAObserver extends Observer{public NBAObserver(String name, Secretary secretary) {super(name, secretary);}//更新状态public void update() {System.out.println(secretary.getAction() + " " + this.name + "不要看篮球了,继续工作。");}}
//股票观察者public class StockObserver extends Observer{public StockObserver(String name, Secretary secretary) {super(name, secretary);}//更新状态public void update() {System.out.println(secretary.getAction() + " " + this.name + "关闭股票行情,继续工作。");}}
第五步:接下来就是测试一下了。我们定义一个通知者、两个观察者,通知者是老板,老板回来的时候通知我们的两个观察者,很糟糕哦~~
//测试/** * 分析:我们使用继承与多态的方式重构了程序,抽象了观察者和通知者,因为观察者可能是在看NBA, * 也可能在看股票或者其他,而通知者也一样,可能是老板,也可能是是我们上司,但是通知者具有相 * 同的行为,于是可以使用接口来定义抽象,使用依赖倒置的原则,可以使得程序的可拓展性大大提高 * ,代码的可重用性也提高。 */public class Test2 {public static void main(String[] args) {Secretary boss = new Secretary(); //通知者Observer xiaowang = new StockObserver("小王", boss); //股票玩家Observer xiaodong = new NBAObserver("小东", boss); //股票玩家//通知者记录boss.attach(xiaowang);boss.attach(xiaodong);//通知者状态发生改变boss.setAction("老板我回来了!");//通知所有的观察者即股票玩家boss.notifyAllObserver();}}
总结:

观察者模式也叫发布-订阅模式。定义:观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象 。这个主题对象在状态发生变化的时,会通知所有的观察者对象,使它们能够自动的更新自己。

遵循的原则:依赖倒置的原则、里氏替换原则。

特点:将一个系统分隔成一系列相互协作的类有一个很不好的副作用,那就是需要维护相互对象将的一致性,我们不希望为了维护一致性而是各类紧密相连,这样会给维护、扩展和重用都带来不便。

使用场景:1.当一个对象改变时需要同时改变其他对象的时候。(不需要知道具体需要改变的对象)







0 0