设计模式——观察者模式

来源:互联网 发布:专业读书软件 编辑:程序博客网 时间:2024/05/29 16:43

一个多月没有写博客了,因为吉哥这阵子在忙着新的项目,今天才空出时间,出了这篇新的设计模式——观察者模式,这是设计模式里面非常重要的模式。

 

观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,让它们能够自动更新自己。

 

观察者模式包含以下四种角色:

 

抽象主题角色:把所有对观察者对象的引用保存在一个集合中,每个抽象主题角色都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类和接口来实现。

 

抽象观察者角色:为所有具体的观察者定义一个接口,在得到主题的通知时更新自己。

 

具体主题角色:在具体主题内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个子类实现。

 

具体观察者角色:该角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。通常用一个子类实现。如果需要,具体观察者角色可以保存一个指向具体主题角色的引用。

 

UML关系图:

 

 

观察者模式UML

比喻:有一个招聘网站,下面有很多注册用户,只要网站公布新的招聘信息,所有的用户都知道网站公布的信息,当用户消掉注册信息时候就接受不到最新的公布信息了。

 

1)先写抽象观察者角色IObserver,里面应该包含一个update方法,当然参数自己需求而定。

/**

 *抽象观察者角色

 */

public interface IObserver {

void update(String content);

}

2)接着创建抽象主题角色,里面要有一个注册方法registerObserver,和一个取消注册方法unregisterObserver,还有一个关键的更新事件方法notifyObservers。

/**

 * @author Administrator

 *抽象主题角色

 */

public interface ISubject {

void registerObserver(IObserver o);

void unregisterObserver(IObserver o);

void notifyObservers(String str);

}

3)具体观察者角色:求职者,求职者覆写父类的update。

/**

 * @author Administrator

 * 具体观察者角色:求职者

 */

public class Jobseeker implements IObserver{

private String jobseeker;

public Jobseeker(String jobseeker){

this.jobseeker=jobseeker;

}

 

public void update(String info) {

System.out.println(jobseeker+":"+info);

}

}

4)接着就是具体主题角色:求职网站,具体角色里面要包含观察者容器,用于刷新每个观察者角色的信息。

/**

 * @author jigo

 *具体主题角色:求职网站

 */

public class JobWebsite implements ISubject{

// 存放观察者

    private List<IObserver> list = new ArrayList<IObserver>();

    public void registerObserver(IObserver o) {

if(!list.contains(o)){

list.add(o);

}

}

public void unregisterObserver(IObserver o) {

if(list.contains(o)){

list.remove(o);

}

}

public void notifyObservers(String str) {

for(IObserver o:list){

o.update(str);

}

}

}

5)最后就是我们的测试步骤,有AB两位求职者,当第一次公布信息的时候,AB都接受到信息了;B消掉了账号,第二次公布信息时候,B没有接收到信息,而A有新的信息;B接着又注册了,第三次公布信息的时候,AB都接收到新的信息了。

public class Client {

public static void main(String[] args) {

ISubject subject=new JobWebsite();

IObserver aObserver=new Jobseeker("A");

IObserver bObserver=new Jobseeker("B");

subject.registerObserver(aObserver);

subject.registerObserver(bObserver);

subject.notifyObservers("招聘一位数学教师!");

subject.unregisterObserver(bObserver);

subject.notifyObservers("招聘一位语文老师!");

subject.registerObserver(bObserver);

subject.notifyObservers("招聘一位英语老师!");

}

}

 

优点:

Subject在发送广播通知的时候,无须指定具体的Observer,Observer可以自己决定是否要订阅Subject的通知。

缺陷:

如果一个Subject被大量Observer订阅的话,在广播通知的时候可能会有效率问题,耗性能。

 

适用场合:

1、 对一个对象状态的更新,需要其他对象同步更新,而且其他对象的数量动态可变。

2、 对象仅需要将自己的更新通知给其他对象而不需要知道其他对象的细节

1 0
原创粉丝点击