观察者模式

来源:互联网 发布:广告录音制作软件 编辑:程序博客网 时间:2024/06/07 02:54

观察者模式定义:

Define a one-to-many dependency between objects so that when one object changes state, all its dependency are notified and updated automatically.

翻译过来就是,定义一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。

观察者模式也叫做发布订阅模式。


场景分析:

其实这种场景在我们生活中非常常见,不知你住没注意,妈妈把饭菜做好了,然后挨个通知你爸爸和你。

我们分析一下这个场景

有三个对象: 爸爸、 妈妈和儿子。其中 妈妈做饭,做好了之后通知爸爸和儿子。

首先,创建Mum对象 他有两个方法做饭cooking()和通知其他人notifyOthers()。

/** * Created by dushangkui on 2017/3/22. */public class Mum {    private Dad dad;    private Son son;    public Mum(Dad dad, Son son) {        this.dad = dad;        this.son = son;    }    public static void main(String[] args) {        Dad dad = new Dad();        Son son = new Son();        Mum mum = new Mum(dad,son);        mum.cooking();        mum.notifyOthers();    }    private void cooking(){        System.out.println("开始做饭");        System.out.println("做饭结束");    }    private void notifyOthers(){        System.out.println("通知其他人吃饭");        dad.onRecive();        son.onRecive();    }}
妈妈持有爸爸和儿子的引用,好通知他们。

爸爸和儿子都要有一个方法去接收这个消息并且做出反应。

/** * Created by dushangkui on 2017/3/22. */public class Dad {    public void onRecive(){        System.out.println("爸爸听到了,正在过去");    }}

/** * Created by dushangkui on 2017/3/22. */public class Son {    public void onRecive(){        System.out.println("儿子听到了,但是不想吃饭");    }}
运行场景:

开始做饭做饭结束通知其他人吃饭爸爸听到了,正在过去儿子听到了,但是不想吃饭

好了,我们忠实的完成了之前的定义,一对多关系,妈妈状态改变了通知爸爸和儿子然后做出变化。但是这个代码真的好烂。为什么说烂呢,不能拥抱变化。如果家庭有好多成员呢,谁中午不想吃饭,谁要吃饭,饭做多了就要剩下,少了就不够吃。现在我们变一下:

先定义一个家庭成员的接口,可以接收消息:

public interface Member {    void onRecive(String msg);}

然后改造爸爸和儿子的类结构,实现Member接口:

public class Dad implements Member {    @Override    public void onRecive(String msg) {        System.out.println("爸爸听到了消息【" + msg + "】,正在过去");    }}

public class Son implements Member {    @Override    public void onRecive(String msg) {        System.out.println("儿子听到了消息【" + msg + "】,但是不想过去");    }}
妈妈也要与时俱进

public class Mum implements Member {    private List<Member> familyMember = new ArrayList<Member>();    public void eating(Member member){        familyMember.add(member);    }    public static void main(String[] args) {        Dad dad = new Dad();        Son son = new Son();        Mum mum = new Mum();        //提前打报告 要不要吃饭? 爸爸要吃饭 儿子不要吃饭        mum.eating(dad);        mum.eating(mum);        mum.cooking();        mum.notifyOthers();    }    private void cooking(){        System.out.println("开始做饭");        System.out.println("做"+familyMember.size()+"个人的饭。");        System.out.println("做饭结束");    }    private void notifyOthers(){        System.out.println("通知其他人吃饭");        for(Member member : familyMember){            member.onRecive("饭做好了");        }    }    @Override    public void onRecive(String msg) {        System.out.println("妈妈也要吃饭啊^.^");    }}

尝试下:

开始做饭做2个人的饭。做饭结束通知其他人吃饭爸爸听到了消息【饭做好了】,正在过去妈妈也要吃饭啊^.^

现在如果多了其他人也能够很好适应,如果儿子想吃饭了 直接想妈妈报告 调用eating方法就好了。提前说 好处多。


从上面我们可以总结出来 ,其实对象分两类:消息的生产者 和消息的消费者










1 0
原创粉丝点击