观察者设计模式Java实现

在设计模式中,观察者模式,通常又称为发布/订阅(Publish/Subscribe)模式,举个例子来理解,

  1、有一个报社

  2、你订阅了这家报社的报纸

  3、报社每次出新报纸就会给你送一份

当然,如果你不想再收到这些报纸了,只需要给报社打个电话取消你的订阅就可以,这其实就是一个观察者模式,也叫做发布订阅模式。报社是被观察者,也叫做发布者,“你”是一个观察者,也叫做订阅者。

 

在通过一个老师学生的例子来举例

  有一个老师,他有一群学生,现在他需要将这些学生的考试成绩通知给他们,如何来实现呢?

  首先来分析,老师通知学生,所以老师是发布者, 学生接收老师通知,是订阅者。

  老师有一个行为,那就是通知学生成绩。  

  学生也有一个行为,那就是接收老师的通知。

  这里有一个和报社发报纸的例子不一样的地方,那就是每个学生的成绩是不一样的,而且为了保护学生,我们不希望学生的成绩会被其他人知道。

  ok,有了这些分析基本就可以开始写代码了

首先,我们需要先定义两个接口,一个是被观察者(发布者),一个是观察者(订阅者)

/**
 * 主题接口,即被观察者接口
 * @author liuyck
 *
 */
public interface Subject {
    
    /**
     * 添加观察者
     * @param id    观察者id
     * @param obj    观察者本身对象
     */
    void addObserver(String id, Observer obj);
    
    /**
     * 移除观察者
     * @param id    观察者id
     */
    void deleteObserver(String id);
    
    /**
     * 当主题方法改变时,这个方法被调用,通知所有的观察者
     * @param msg 通知消息
     */
    void notifyObservers(Object msg);
    
    /**
     * 当主题方法改变时,这个方法被调用,通知指定观察者
     * @param id    观察者id
     * @param msg    通知消息
     */
    void notifyObserver(String id,Object msg);
}
/**
 * 观察者接口
 * @author liuyck
 *
 */
public interface Observer { 
    
    /**
     * 当主题状态改变时,观察者更新数据
     * @param msg
     */
    void update(Object msg);
}

被观察者接口具有添加观察者、删除观察者、通知所有观察者、通知指定观察者的行为。

观察者接口具有更新数据的行为。

 

接口订好了,下面就是具体实现了。

老师的实现

/**
 * 老师类
 * @author liuyck
 *
 */
public class TeacherSubject implements Subject{
    
    /**
     * 学生Map
     */
    private Map<String, Observer> observerMap = new HashMap<String, Observer>();

    @Override
    public void addObserver(String id, Observer obj) {
        observerMap.put(id, obj);
    }

    @Override
    public void deleteObserver(String id) {
        observerMap.remove(id);
    }

    @Override
    public void notifyObservers(Object msg) {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void notifyObserver(String id, Object msg) {
        observerMap.get(id).update(msg);
    }
}

 

学生的实现

/**
 * 学生类
 * @author liuyck
 *
 */
public class StudentObserver implements Observer{
    private String name;
    
    /**
     * 每一个学生有一个唯一的名称和一位老师
     * @param name
     * @param t
     */
    public StudentObserver(String name,TeacherSubject t) {
        this.name=name;
        //每新建一个学生对象,默认添加到观察者的行列
        t.addObserver(name, this);
    }
    
    @Override
    public void update(Object msg) {
        System.out.println("学生" + this.name + "收到消息:" + msg);
    }
}

 

测试方法

/**
 * 老师学生观察者模式测试类
 * @author liuyck
 *
 */
public class DemoTest {
    
    public static void main(String[] args) {    
        TeacherSubject teacher = new TeacherSubject();

        new StudentObserver("jack", teacher);
        new StudentObserver("john", teacher);
        
        teacher.notifyObserver("jack", "你考了99分");
        teacher.notifyObserver("john", "你考了59分");
    }
}

 

posted @ 2018-01-29 15:48  源代码007  阅读(281)  评论(0编辑  收藏  举报