观察者模式

观察者模式定义:

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值