设计模式学习笔记---观察者模式Observer pattern(Java版)

来源:互联网 发布:软件测试的思路 编辑:程序博客网 时间:2024/04/20 05:13

一、场景

网站上,很多人订阅了“NBA主题”新闻,当有这个主题新闻时,就会将这些新闻发给所有订阅的人。(我们可以把多个订阅者、客户称之为观察者;需要同步给多个订阅者的数据封装到对象中,称之为目标。)

二、实质

广播机制 
观察者主要用于1:N的通知。当一个对象(目标对象Subject或Objservable)<消息发布>的状态变化时,他需要及时告知一系列对象(观察者对象Observer)<消息订阅>,令他们做出响应。 
通知观察者的方式: 
推 
–每次都会把通知以广播方式发送给所有观察者,所有观察者只能被动接收。 
拉 
–观察者只要知道有情况即可。至于什么时候获取内容,获取什么内容,都可以自主决定。

三、示例

 
方式一 自己实现

package com.lgd.observer;public interface Observer {    void update(Subject subject);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
package com.lgd.observer;import java.util.ArrayList;import java.util.List;public class Subject {    protected List<Observer> list = new ArrayList<Observer>();    public void register(Observer obs){        list.add(obs);    }    public void removeObserver(Observer obs){        list.remove(obs);    }    //通知所有的观察者更新状态    public void notifyAllObservers(){        for(Observer obs:list)        {            obs.update(this);        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
package com.lgd.observer;public class ConcreteSubject extends Subject{    private int state;    public int getState() {        return state;    }    public void setState(int state) {        this.state = state;        //主题对象(目标对象)只发生了变化,请通知所有的观察者。        this.notifyAllObservers();    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
package com.lgd.observer;public class ObserverA implements Observer{    private int myState;//myState需要与目标对象的state保持一致!    @Override    public void update(Subject subject) {        myState = ((ConcreteSubject)subject).getState();    }    public int getMyState() {        return myState;    }    public void setMyState(int myState) {        this.myState = myState;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
package com.lgd.observer;public class Client {    public static void main(String[] args) {        //目标对象        ConcreteSubject subject = new ConcreteSubject();        //创建多个观察者        ObserverA obs1 = new ObserverA();        ObserverA obs2 = new ObserverA();        ObserverA obs3 = new ObserverA();        //将这三个观察者添加到subject对象的观察者队伍中        subject.register(obs1);        subject.register(obs2);        subject.register(obs3);        //修改subject的状态        subject.setState(3000);        System.out.println("========");        //看看观察者的状态是否也发生了变化        System.out.println(obs1.getMyState());        System.out.println(obs2.getMyState());        System.out.println(obs3.getMyState());        //修改subject的状态        subject.setState(100);        System.out.println("========");        //看看观察者的状态是否也发生了变化        System.out.println(obs1.getMyState());        System.out.println(obs2.getMyState());        System.out.println(obs3.getMyState());    }}   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

运行结果: 
======== 
3000 
3000 
3000 
======== 
100 
100 
100

方式二 
JavaSE提供了Java.util.Observable和java.util.Observer来实现观察者模式 此方法通知次序会改变

package com.lgd.observer2;import java.util.Observable;//目标对象public class ConcreteSubject extends Observable{    private int state;    public void set(int s){        state = s;//目标对象的状态发生了改变        setChanged();//表示目标对象已经做了更改        notifyObservers(state);//通知所有的观察者    }    public int getState() {        return state;    }    public void setState(int state) {        this.state = state;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
package com.lgd.observer2;import java.util.Observable;import java.util.Observer;//观察者public class ObserverA implements Observer{    private int myState;    @Override    public void update(Observable o, Object arg) {        myState = ((ConcreteSubject)o).getState();    }    public int getMyState() {        return myState;    }    public void setMyState(int myState) {        this.myState = myState;    }   }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
package com.lgd.observer2;public class Client {    public static void main(String[] args) {        //创建目标对象Obserable        ConcreteSubject subject = new ConcreteSubject();        //创建观察者        ObserverA obs1 = new ObserverA();           ObserverA obs2 = new ObserverA();        ObserverA obs3 = new ObserverA();        //将上面三个对象添加到目标对象subject的观察者中        subject.addObserver(obs1);        subject.addObserver(obs2);        subject.addObserver(obs3);        //改变subject对象的状态        subject.set(3000);        System.out.println("========");        System.out.println(obs1.getMyState());        System.out.println(obs2.getMyState());        System.out.println(obs3.getMyState());        //改变subject对象的状态        subject.set(500);        System.out.println("========");        System.out.println(obs1.getMyState());        System.out.println(obs2.getMyState());        System.out.println(obs3.getMyState());    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

运行结果: 
======== 
3000 
3000 
3000 
======== 
500 
500 
500

四、应用场景

–聊天程序的服务器转发给所有客户端 
–网络游戏(多人联机对战)场景中,服务器将客户端的状态进行分发 
–邮件订阅 
–Servlet中,监听器的实现。 
–Android中,广播机制 
–JDK的AWT中事件处理模型基于观察者模式的委派事件模型 
事件源–目标对象 
事件监听器–观察者 
–京东商城中,群发某商品打折信息

0 0
原创粉丝点击