观察者模式(Observer)

多个观察者关注同一个目标,当目标发生改变时,观察者们可以收到消息。

(立刻更新消息,或者想知道的时候更新消息。)

实现:

  1、自定义观察者:观察者与目标有一致的状态属性,目标持有观察者的引用。

  2、jdk自带的:

      java.util.Observable 类,实现它的类即可被观察(目标类)。

      核心方法:

setChanged();//通知观察者目标的信息已经修改
notifyObservers(state);//传入状态,修改观察者们通过update方法可获得state,即可修改状态

      java.util.Observer接口,实现它的类需要重写update 方法,昨晚观测者。

void update(Observable var1, Object var2);//var1 为目标对象,var为传过来的状态。

 


 

自定义观察者:

1、观察者接口:有观察者的统一方法:更新

public interface Observer {
    void update(Subject subject);//更新数据
}

2、具体观察者:

public class MyObserver implements Observer{
    private int myState;//统一状态变量

    @Override
    public void update(Subject s) {
        //改变为指定的状态
        myState = ((ConcreteSubject)s).getState();
    }

    public int getMyState() { return myState; }

    public void setMyState(int myState) { this.myState = myState; }
}

3、目标父类:统一需要实现的方法。

public class Subject {
    //观察者们
    protected List<Observer> list = new ArrayList<>();

    //注册一个观察者
    public void registerObserver(Observer o){ list.add(o); }
    //移除一个观察者
    public void removeObserver(Observer o){ list.remove(o); }
    //通知观察者们进行更新
    public void notifyAllObersvers(){
        for(Observer o:list){
            o.update(this);//更新为此时状态
        }
    }
}

4、目标:此处设计为目标状态一改变,就更新观察者们的状态。

public class ConcreteSubject extends Subject{
    private int state;//状态变量

    public int getState() { return state; }

    public void setState(int state) {
        this.state = state;
        //状态一改变,就通知观察者们更新状态
        this.notifyAllObersvers();
    }
}

测试:

public class Client {
    public static void main(String[] args) {
        //创建目标
        ConcreteSubject  cs = new ConcreteSubject();
        //创建三个观察者
        MyObserver m1 = new MyObserver();
        MyObserver m2 = new MyObserver();
        MyObserver m3 = new MyObserver();
        //注册观察者
        cs.registerObserver(m1);
        cs.registerObserver(m2);
        cs.registerObserver(m3);

        System.out.println("m1状态为:"+m1.getMyState());
        System.out.println("m2状态为:"+m2.getMyState());
        System.out.println("m3状态为:"+m3.getMyState());
        //移除观察者3
        cs.removeObserver(m3);

        //改变状态
        cs.setState(123);


        System.out.println("m1状态为:"+m1.getMyState());
        System.out.println("m2状态为:"+m2.getMyState());
        System.out.println("m3状态为:"+m3.getMyState());
    }
}

测试结果:

 

 

 


 

使用jdk提供的目标父类 Observable 及观察者接口 Observer 实现

1、创建目标:

public class ConcreteSubject extends Observable {
    private int state;//统一的状态

    public void setState(int state) {
        this.state = state;
        setChanged();//目标的信息已经修改
        notifyObservers(state);//通知观察者们
    }

    public int getState() {
        return state;
    }
}

2、确定观察者模式:状态一变我就更新

public class MyObserver implements Observer {
    private int myState;//统一的状态类型

    @Override
    public void update(Observable observable, Object o) {
        //状态更新
        //方式1:
        myState = (int)o;
        //方式2:
        //myState = ((ConcreteSubject)observable).getState();
    }

    public int getMyState() { return myState; }

    public void setMyState(int myState) { this.myState = myState; }
}

3、测试:

public class Client {
    public static void main(String[] args) {
        //创建目标
        ConcreteSubject cs = new ConcreteSubject();
        //创建观察者
        MyObserver m1 = new MyObserver();
        MyObserver m2 = new MyObserver();
        MyObserver m3 = new MyObserver();
        //注册观察者
        cs.addObserver(m1);
        cs.addObserver(m2);
        cs.addObserver(m3);

        //查看状态
        System.out.println("m1状态为:"+m1.getMyState());
        System.out.println("m2状态为:"+m2.getMyState());
        System.out.println("m3状态为:"+m3.getMyState());
        
        //移除观察者2
        cs.deleteObserver(m2);
        
        //改变目标状态
        cs.setState(199);
        
        //查看状态
        System.out.println("m1状态为:"+m1.getMyState());
        System.out.println("m2状态为:"+m2.getMyState());
        System.out.println("m3状态为:"+m3.getMyState());
    }
}

测试结果:

 


 

 不过,在jdk 9 中这种方式被弃用了。

 

posted @ 2022-11-27 13:10  在博客做笔记的路人甲  阅读(328)  评论(0编辑  收藏  举报