大话设计模式-第14章 老板回来,我不知道--观察者模式- 高飞网

第14章 老板回来,我不知道--观察者模式

2016-02-02 11:59:55.0

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


场景:

同事A和B与前台约好,如果老板回公司,事先通知他们,以免他们在看股票或NBA时被发现。 


//主题类
public interface Subject{
        public void attach(Observer observer);
        public void detach(Observer observer);
        //通知接口
        public void doNotify();
        public String getState();
        public void setState(String state);
}
import java.util.*;
//老板主题类
public class BossSubject implements Subject
{
        //观察者集合
        private List<Observer> observerList = new ArrayList<Observer>();
        private String state;//状态

        //增加观察者
        public void attach(Observer observer){
                this.observerList.add(observer);
        }
        //剔除观察者
        public void detach(Observer observer){
                this.observerList.remove(observer);
        }
        //遍历观察者并通知
        public void doNotify(){
                for(Observer o :observerList){
                        o.update();
                }
        }
        public String getState(){
                return this.state;
        }
        public void setState(String state){
                this.state = state ;
        }
}
import java.util.*;
//前台主题类
public class SecretarySubject implements Subject
{
        //观察者集合
        private List<Observer> observerList = new ArrayList<Observer>();
        private String state;  

        //增加观察者
        public void attach(Observer observer){
                this.observerList.add(observer);
        }
        //剔除观察者
        public void detach(Observer observer){
                this.observerList.remove(observer);
        }
        //遍历观察者并通知
        public void doNotify(){
                for(Observer o :observerList){
                        o.update();
                }
        }
        public String getState(){
                return this.state;
        }
        public void setState(String state){
                this.state = state;
        }
}
public abstract class Observer{
        protected String name;
        protected Subject subject;
        public Observer(String name,Subject subject){
                this.name = name;
                this.subject = subject;
        }      
        //状态发生时更新状态
        public abstract void update(); 
}
//观察者类
public class NBAObserver extends Observer{
        public NBAObserver(String name,Subject subject){
                super(name,subject);
        }              
        public void update(){
                System.out.println(subject.getState()+","+name+"关闭NBA直播,继续工作");
        }
}
//股票观察者类
public class StockObserver extends Observer{
        public StockObserver(String name,Subject subject){
                super(name,subject);
        }              
        public void update(){
                System.out.println(subject.getState()+","+name+"关闭股票行情,继续工作");
        }
}
public class App{
        public static void main(String[] args){
                SecretarySubject secretary = new SecretarySubject();

                StockObserver tongshi1 = new StockObserver("小薇",secretary);
                NBAObserver tongshi2 = new NBAObserver("小易",secretary);

                //添加观察者
                secretary.attach(tongshi1);
                secretary.attach(tongshi2);
                //主题状态改变
                secretary.setState("老板回来了");
                secretary.doNotify();

        }
}

 

下面是观察者模式类图:



特点:将一个系统分割成一系列相互协作的类有一个很不好的副作用,那就是需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,这样会给维护、扩展和重用都带来不便。
场景:当一个对象的改变需要同时改变其他对象,而且它不知道有多少对象待改变的时候,应该考虑使用观察者模式。

不足:当系统已经形成,而且众多观察者角色,并没有使用相同的接口时(如上面的update方法),就没法用现在的方式使用观察者模式了。同时也就没有观察者抽象类了,所以如下有两个具体的观察者类,它们有各自不同的方法。此时主题类中也没的抽象的观察者类了,只有一个通知接口。

//股票观察者类
public class StockObserver {
        private String name;
        private Subject subject;

        public StockObserver(String name,Subject subject){
                this.name = name;
                this.subject = subject;
        }              
        //具体方法
        public void closeStockMarking(){
                System.out.println(subject.getState()+","+name+"关闭股票行情,继续工作");
        }
}
//观察者类
public class NBAObserver{
        private String name;
        private Subject subject;
        public NBAObserver(String name,Subject subject){
                this.name = name;
                this.subject = subject;
        }              
        //具体方法
        public void closeNBADirectSeeding(){
                System.out.println(subject.getState()+","+name+"关闭NBA直播,继续工作");
        }
}
//主题类
public interface Subject{
        //通知接口
        public void doNotify();
}
import java.util.*;
//前台主题类
public class SecretarySubject implements Subject
{
    //观察者集合
    private String state;  
    private EventHandler update;

    //遍历观察者并通知
    public void doNotify(){
        update.xnotify();
    }  
    public String getState(){
        return this.state;
    }  
    public void setState(String state){
        this.state = state;
    }  
}