观察者设计模式(Observer)

观察者设计模式

     是对象的行为模式,又称发布/订阅模式(publish/subscribe)模式,模/视图模式(model/view),源-监听模式(source/listener)

     观察者模式定义一种一对多的依赖关系。让多个观察者同时监听一个主体对象,当主题对象的状态发生改变时,会通知所有的观察者,使其自动的更新自己。(相对

registerListener是一种一对一的关系,称为回调)。


观察者模式的结构

      


    由上图我们可以知道观察者模式的组成:

抽象主题对象(Subject):抽象主题对象会把所有的观察者对象的引用保存在一个集合当中(通畅是ArrayList),抽象主题对象可以保存任意个观察者对象。提供两个

                                                   接口用于添加观察者对象,和删除观察者对象。定义一个Notify**方法,会逐个调用 观察者自身方法更新自己。抽象主体对象也叫作被观察者

                                                    对象(Observable);

具体主体对象(ConcreteSubject):将相关的状态存入具体观察者对象中,当具体观察者对象的状态发生改变时,会逐个通知被注册的观察者对象。

抽象观察者对象(Observer):为具体观察者定义一个统一的接口,在主体对象通知更新自身时调用此方法。

具体观察这对象(ConcreteObserver):存储一个与主题对象状态相协调的状态。实现抽象观察者对象的更新自身的方法。


源码:

抽象主题:

public class Subject {
    
    ArrayList<Observer> observers;
    
    public Subject() {
        observers=new ArrayList<Observer>();
    }
    
    /**
     * 注册
     * @param obs
     */
    public void attach(Observer obs){
        if(obs ==  null){
            throw new NullPointerException();
        }
        
        observers.add(obs);
    }
    
    /**
     * 注销
     * @param obs
     */
    public void detach(Observer obs){
        observers.remove(obs);
    }

    
    protected void notifyObservers(String newState) {
        
        for(Observer obs:observers){
            obs.update(newState);
        }
    }
}

具体主题对象:

public class ConcreteSubject extends Subject{
    
    private String state;
    
    public String getState(){
        return state;
    }
    
    public void change(String newState){
        state=newState;
        System.out.println("主题状态:"+state);
        notifyObservers(state);
    }
}

抽象观察者对象:

public interface Observer {
    
    public void update(String newState);

}

具体观察者对象:

public class ConcreteObserver implements Observer{
    
    private String observerState;

    @Override
    public void update(String newState) {
        observerState = newState;
        System.out.println("观察者转态:"+newState);
    }

}

客户端对象:

public class Client {
    
    public static void main(String[] args) {
        ConcreteSubject subject =new ConcreteSubject();
        Observer obs=new ConcreteObserver();
        subject.attach(obs);
        subject.change("newstate");
    }

}

运行结果:


主题状态:newstate
观察者转态:newstate


推模式和拉模式

    观察者模式根据update的传参不同分为推模式和拉模式。

    推模式:主体对象向观察者对象推送主体对象的详细信息,不过观察者对象是否需要。(上面就是推模式)

    拉模式:主题对象把自身的引用传递给观察者对象。观察者对象想用什么信息,直接通过主题对象的引用自己获取。

拉模式源码(在上面的基础做局部修改):

抽象主题:

public class Subject {
    
    ArrayList<Observer> observers;
    
    public Subject() {
        observers=new ArrayList<Observer>();
    }
    
    /**
     * 注册
     * @param obs
     */
    public void attach(Observer obs){
        if(obs ==  null){
            throw new NullPointerException();
        }
        
        observers.add(obs);
    }
    
    /**
     * 注销
     * @param obs
     */
    public void detach(Observer obs){
        observers.remove(obs);
    }

    
    protected void notifyObservers() {
        
        for(Observer obs:observers){
            obs.update(this);
        }
    }
}

具体主题对象:

public class ConcreteSubject extends Subject{
    
    private String state;
    
    public String getState(){
        return state;
    }
    
    public void change(String newState){
        state=newState;
        System.out.println("主题状态:"+state);
        notifyObservers();
    }
}

抽象观察者:

public interface Observer {
    
    public void update(Subject sub);

}

具体观察者:

public class ConcreteObserver implements Observer{
    
    private String observerState;

    @Override
    public void update(Subject sub) {
        
        observerState = ((ConcreteSubject)sub).getState();
        System.out.println("观察者转态:"+observerState);
    }

}

客户端:
public class Client {
    
    public static void main(String[] args) {
        ConcreteSubject subject =new ConcreteSubject();
        Observer obs=new ConcreteObserver();
        subject.attach(obs);
        subject.change("newstate");
    }

}

推模式是假定主体对象知道观察者需要的数据类型,拉模式则是主体对象不知道观察者需要的数据类型,所以干脆将自身引用传递过去,观察者对象需要什么对象自己去取。

推模式的update方法是按需要定义参数,很难被复用。拉模式则只需在接口处多定义一个取参数的接口,就可以实现复用。







       

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值