设计模式之一:观察者模式

一.  前言


    观察者模式是非常常见的一种设计模式。其主要用于多个对象需要对同一个对象进行监听的情况,(即多对一)。曾经看过大话设计模式,依稀记得如下这个例子,大意为,曾经员工上班偷懒,被老板看到了,难为情,于是乎,从此之后,当员工偷懒的时候,都会提前给前台小姑娘打个招呼,当老板来的时候,通知下自己,某一天,有三个员工A,B,C偷懒,均给小姑娘打了招呼,当老板来的时候,小姑娘都通知到了,于是老板静静的来,又静静的走了。抽象这个通知的过程,就是典型的观察者模式,简图如下所示:

                                                     
                                                                                                              1. 1  观察者模式原理
  观察者模式中基本包含观察者(A,B,C),被观察者(前台小姑娘),时间源(boss来了)。而观察者和被观察者直接的纽带就是回调那一套机制(具体可参考上一篇文档)。通过注册,被观察者保存了各个观察者的回调对象。于是当时间源发生的时候,会把自己的保存的对象统统通知一次。如果任务完成了,观察者解除注册。

二. 案例实现观察者模式

下面我们来实现这个过程,编程语言java,编程软件android studio:

1. 监听器,也是回调接口

(接口可以让程序面向抽象,而不面向实际的对象,减小代码的耦合度,可以大大提高程序可扩展性),用于回调发通知。
 
   
package com.example.test;
public interface Listener {
    void onCallBack();
}

2. 被观察者

主要保存观察者接口对象(注册和解除注册来增加和减少对象),监听时间源,向各个对象发送通知。
package com.example.test;
import java.util.ArrayList;
import java.util.List;

public class Secretary {
    public String name;
    private List<Listener> liseners = new ArrayList<Listener>();
    public Secretary(String str) {
        name = str;
    }
    public void addLisener(Listener lisener) {
        if (liseners == null) {
            liseners = new ArrayList<Listener>();
        }

        if (lisener != null)
            showLog("Add lisener =" + lisener.toString());
        liseners.add(lisener);
    }

    public void deleteLisener(Listener lisener){
        if (liseners == null){
            liseners = new ArrayList<Listener>();
        }
        if(lisener != null && liseners.contains(lisener)){
            showLog("Delete listener = "+lisener.toString());
            liseners.remove(lisener);
        }
    }

    private void showLog(String str){
        System.out.println(str);
    }

    private void nofifyAll(){
        if (liseners.size() < 1){
            return;
        }
        for(Listener lisener : liseners) {
            lisener.onCallBack();
        }
    }
    
    public void simulateBossComing(){
        new Thread(){
            @Override
            public void run() {
                try{
                    sleep(3000);
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
                nofifyAll();
            }
        }.start();
    }
}

 

3. 观察者 

主要向被观察者提供监听器(接口的implent对象),并且实现回调接口。

观察者A

package com.example.test;

public class PersonA {

    private String name;
    public PersonA(String str){
        name = str;
    }
    public Listener getMyListener(){
        return new PersonAListeer();
    }
    public class PersonAListeer implements Listener {
        @Override
        public void onCallBack() {
            System.out.println("PersonA, The boss is comming right now!");
        }
    }
}

 

观察者B


package com.example.test;

public class PersonB {
    private String name;
    public PersonB(String str){
        name = str;
    }
    public Listener getMyListener(){
        return new PersonBListener();
    }
    public class PersonBListener implements Listener {
        @Override
        public void onCallBack() {
            System.out.println("PersonB, The boss is comming right now!");
        }
    }
}

4. 测试类


package com.example.test;

/**
 * Task: Two worker, one secretary,one boss
 * If the boss is comming to the office,found by the secretary and notify the listener.
 */
public class MyClass {
    public static void main(String[] args){
        PersonA personA = new PersonA("PersonA");
        PersonB personB = new PersonB("PersonB");
        Secretary secretary = new Secretary("Girl");
        secretary.addLisener(personA.getMyListener());
        secretary.addLisener(personB.getMyListener());
        secretary.simulateBossComing();
    }
}

5.测试结果:

        Add lisener =com.example.test.PersonA$PersonAListeer@75b84c92
        Add lisener =com.example.test.PersonB$PersonBListener@6bc7c054
        PersonA, The boss is comming right now!
        PersonB, The boss is comming right now!

        Process finished with exit code 0


三 结论:

     本文的案例初步实现了这个观察者设计思想,仅仅是个人的一点理解,案例只是一个小Demo,有错误敬请原谅。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值