您的位置:首页 > 其它

设计模式之观察者模式

2014-12-09 16:51 351 查看
在现实生活中,有许许多多这样的例子,比如说你关注了我的博客,我有新的内容更新了,就会有推送消息告诉你我有内容更新了,如果你没有关注我的博客,就不会有推送消息告诉你我有内容更新了,这些就是观察者模式。

观察者模式有一个主题,有许许多多的观察者,人们可以选择注册成为该主题的观察者,观察者也可以选择取消观察该主题。加入你是该主题的一员,那么该主题有东西更新了,主题就会提醒你它有内容更新了,如果你不是观察者,就不会提醒你。这也是一种很微妙的设计模式。

下面就由一个比较简单地例子来介绍一下观察者模式。

假如在动物的世界里也有报纸,报纸的名字叫做Subject,森林里有老鼠,鸭子,狗等生物,他们和谐地生活着... ...有一天,动物们发现有这么一种报纸,然后他们就纷纷注册成为Subject报纸的观察者,然后每次报纸有新版出来的时候,动物们都会收到相应的新版报纸。有一天,老鼠突然觉得这份报纸没有意思了,他就取消了对Subject报纸的关注,然后他就不会再收到报纸了。(当然,如果有一天他怀念报纸的内容了,他也可以再次注册为观察者),下面是类图



上面给出了类图,下面让我们来看看具体的Java实现

Observer接口

package observersMode;

public interface Observer {
//观察者在主题出现修改时更新
public void update();
}


Subject主题类

package observersMode;

import java.util.ArrayList;

public class Subject {
ArrayList<Observer> observers = null;

public Subject() {
observers = new ArrayList<Observer>();
}

public void addObserver(Observer o) {
observers.add(o);
}

public void deleteObserver(Observer o) {
for (int i = 0; i < observers.size(); ++i) {
if (observers.get(i) == o) {
observers.remove(i);
}
}
}

//当主题有变化时,调用modify通知所有观察者
public void modify() {
for (int i = 0; i < observers.size(); ++i) {
(observers.get(i)).update();
}
}
}


观察者Mouse类


package observersMode;

public class Mouse implements Observer {

private Subject subject = null;

public Mouse(Subject subject){
this.subject = subject;
}

@Override
public void update() {
System.out.println("I am mouse, I have received the news");
}

public void register(){
subject.addObserver(this);
}

public void remove(){
subject.deleteObserver(this);
}

}


观察者Duck类

package observersMode;

public class Duck implements Observer {

private Subject subject = null;

public Duck(Subject subject){
this.subject = subject;
}

@Override
public void update() {
System.out.println("I am duck, I have received the news");
}

public void register(){
subject.addObserver(this);
}

public void remove(){
subject.deleteObserver(this);
}

}


观察者Dog类

package observersMode;

public class Dog implements Observer {

private Subject subject = null;

public Dog(Subject subject) {
this.subject = subject;
}

@Override
public void update() {
System.out.println("I am dog, I have received the news");
}

public void register() {
subject.addObserver(this);
}

public void remove() {
subject.deleteObserver(this);
}

}


测试文件

package observersMode;

public class Test {

/**
* @param args
*/
public static void main(String[] args) {
Subject subject = new Subject();
Mouse mouse = new Mouse(subject);
Duck duck = new Duck(subject);
Dog dog = new Dog(subject);

System.out.println("No observer now");
subject.modify();
System.out.println();

System.out.println("One observer now");
mouse.register();
subject.modify();
System.out.println();

System.out.println("Two observer now");
duck.register();
subject.modify();
System.out.println();

System.out.println("Three observer now");
dog.register();
subject.modify();
System.out.println();

System.out.println("Two observer now");
dog.remove();
subject.modify();
System.out.println();
}

}


总结

总的来说,观察者模式适用于一对多的情况,在做这篇博客的过程中也发现一些问题,比如观察者注册register和取消观察remove是高度重复的,但是java7暂时不支持在接口里写具体的实现,所以也没办法,听说java8可以做到这些,这些大家可以去试一下。也许有人会说那么为什么不写成虚类呢?其实如果写成虚类,确实可以达到效果,但是就违反了设计原则少用继承了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: