您的位置:首页 > 其它

设计模式之观察者模式案例学习

2013-02-26 23:45 721 查看
转载请注明出处:http://blog.csdn.net/droyon/article/details/8615794

观察者模式:

定义:定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并更新。----HeadFirst设计模式

案例代码下载

案例:

小花猫和猫头鹰以捉老鼠为生。现在有一个广播老鼠信息的主题。可小花狗也参合进来了。

Observable.java

public interface Observable {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObserver();
}


Observer.java

public interface Observer {
public void update(Observable o,Object obj);
}


Subject.java    主题,实现了Observable,发现老鼠,进行广播

import java.util.ArrayList;

public class Subject implements Observable{
private ArrayList<Observer> mValues = new ArrayList<Observer>();
private Content mBody = new Content();

public Subject(){
}

@Override
public void registerObserver(Observer o) {
mValues.add(o);
}

@Override
public void removeObserver(Observer o) {
mValues.remove(o);
}

@Override
public void notifyObserver() {
for(Observer o :mValues){
o.update(this, mBody);
}
}

public void findMouse(String name,int num){
Content content = new Content(name, num);
mBody = content;
notifyObserver();
}

class Content{
private String mName;
private int mNum;

public Content(){
this(null,0);
}

public Content(String name,int num){
mName = name;
mNum = num;
}
@Override
public String toString() {
return "在"+mName+"家,有"+mNum+"只老鼠";
}
}

}


CatObserver.java 观察者,实现了Observer。观察Subject主题,如果Subject进行通知,就是收到通知信息

public class CatObserver implements Observer{
private String mName;
public CatObserver(String name){
mName = name;
}

public void registerSubjectObserver(Observable observable){
System.out.println("我是"+mName+",我注册成为了观察者,我要捉老鼠");
observable.registerObserver(this);
}

@Override
public void update(Observable o, Object obj) {
if(o instanceof Subject){
System.out.println(mName+"收到了通知:"+obj);
}else if(o instanceof DogObserver2){
System.out.println(mName+"接收到小狗共享的信息:"+obj);
}
}

}


DogObserver.java

public class DogObserver implements Observer{
private String mName;

public DogObserver(String name){
mName = name;
}

public void registerSubjectObserver(Observable observable){
System.out.println("我是"+mName+",我注册了成为了观察者,我要狗拿耗子");
observable.registerObserver(this);
}

@Override
public void update(Observable o, Object obj) {
if(o instanceof Subject){
System.out.println(mName+"收到了通知:"+obj);
}
}

}


Maotouying.java

public class Maotouying implements Observer{
private String mName;
public Maotouying(String name){
mName = name;
}

public void registerSubjectObserver(Observable observable){
System.out.println("我是"+mName+",我注册成为了观察者");
observable.registerObserver(this);
}

@Override
public void update(Observable o, Object obj) {
if(o instanceof Subject){
System.out.println(mName+"收到了通知:"+obj);
}
}
}


ObserverTest.java

public class ObserverTest {
public static void main(String args[]){
Subject subject = new Subject();

DogObserver dog = new DogObserver("小花狗");
CatObserver cat = new CatObserver("小花猫");
Maotouying owl = new Maotouying("猫头鹰");

//注册成为观察者,subject发现耗子,就会通知的
dog.registerSubjectObserver(subject);
cat.registerSubjectObserver(subject);
System.out.println("----------------------------------------");
System.out.println("发现老鼠,发出通知:");
subject.findMouse("小丽家", 3);
System.out.println("----------------------------------------");
System.out.println("【想让猫头鹰也接收到通知,很容易扩展实现】");
owl.registerSubjectObserver(subject);
System.out.println("----------------------------------------");
System.out.println("发现老鼠,发出通知:");
subject.findMouse("小张家", 9);
}
}


测试结果:

我是小花狗,我注册了成为了观察者,我要狗拿耗子

我是小花猫,我注册成为了观察者,我要捉老鼠

----------------------------------------

发现老鼠,发出通知:

小花狗收到了通知:在小丽家家,有3只老鼠

小花猫收到了通知:在小丽家家,有3只老鼠

----------------------------------------

想让猫头鹰也接收到通知,很容易扩展实现

我是猫头鹰,我注册成为了观察者

----------------------------------------

发现老鼠,发出通知:

小花狗收到了通知:在小张家家,有9只老鼠

小花猫收到了通知:在小张家家,有9只老鼠

猫头鹰收到了通知:在小张家家,有9只老鼠

扩展:猫头鹰意识到它喜欢的是田鼠,不是耗子,它决定不再接收通知。小花狗也意识到它在多管闲事,它决定将信息分享(观察者可以成为主题,主题也可以成为观察者)

DogObserver2.java

import java.util.ArrayList;

public class DogObserver2 implements Observable,Observer{
private ArrayList<Observer> mData = new ArrayList<Observer>();
private String mName;
private Object content;
private boolean checked = false;

public DogObserver2(String name) {
mName = name;
}

public void registerSubjectObserver(Observable observable){
System.out.println("我是"+mName+",我注册了成为了观察者,我要狗拿耗子");
observable.registerObserver(this);
}

@Override
public void registerObserver(Observer o) {
mData.add(o);
}

@Override
public void removeObserver(Observer o) {
mData.remove(o);
}

@Override
public void notifyObserver() {
for(Observer observer:mData){
observer.update(this, content);
}
}

@Override
public void update(Observable o, Object obj) {
content = obj;
if(checked){
System.out.println(mName+"不在狗拿耗子,分享耗子信息给他人");
notifyObserver();
}else{
System.out.println(mName+"收到了通知:"+obj);
}
}

public void setChecked(boolean check){
checked = check;
}
}


ObserverTest2.java

public class ObserverTest2 {
public static void main(String args[]){
Subject subject = new Subject();

CatObserver cat1 = new CatObserver("小花猫1号");

DogObserver2 dog = new DogObserver2("小花狗");
CatObserver cat2 = new CatObserver("小花猫2号");
CatObserver cat3 = new CatObserver("小花猫3号");

Maotouying owl = new Maotouying("猫头鹰");

cat1.registerSubjectObserver(subject);//花猫注册主题
owl.registerSubjectObserver(subject);//猫头鹰注册主题
dog.registerSubjectObserver(subject);//小狗注册主题
cat2.registerSubjectObserver(dog);//花猫2号,注册小狗主题,成为”小狗“的观察者
cat3.registerSubjectObserver(dog);

subject.findMouse("小赵", 8);

System.out.println("猫头鹰不想接收通知了");
subject.removeObserver(owl);
System.out.println("小狗决定不再多管闲事,分享耗子信息给他人");
dog.setChecked(true);

subject.findMouse("小王", 2);
}
}


测试结果:

我是小花猫1号,我注册成为了观察者,我要捉老鼠

我是猫头鹰,我注册成为了观察者

我是小花狗,我注册了成为了观察者,我要狗拿耗子

我是小花猫2号,我注册成为了观察者,我要捉老鼠

我是小花猫3号,我注册成为了观察者,我要捉老鼠

小花猫1号收到了通知:在小赵家,有8只老鼠

猫头鹰收到了通知:在小赵家,有8只老鼠

小花狗收到了通知:在小赵家,有8只老鼠

猫头鹰不想接收通知了

小狗决定不再多管闲事,分享耗子信息给他人

小花猫1号收到了通知:在小王家,有2只老鼠

小花狗不在狗拿耗子,分享耗子信息给他人

小花猫2号接收到小狗共享的信息:在小王家,有2只老鼠

小花猫3号接收到小狗共享的信息:在小王家,有2只老鼠

jdk中也实现了观察者模式,本案例也可以使用jdk来实现。

总结:

HearFirst设计模式:
观察者模式提供了一中松耦合的代码设计,当两个对象松耦合时,他们依然可以交互,但是不清楚彼此的细节。观察者模式提供了一种对象设计,让主题和观察者模式之间可以松耦合。

关于观察者的一切,主题只知道观察者模式实现了某个接口,主题也不必知道观察者的具体类是谁,做了什么。

任何时候我们都可以增加、删除观察者,并且主题不受影响。因为主题唯一依赖的是实现了Observer接口的对象。

当有新类型的观察者出现时,我们不必须为了兼容新类型而去修改主题,我们只需让新类型观察者实现Observer接口,然后注册成为观察者。主题只会发送通知给所有实现了观察者接口的对象。

我们可以很容易的使用这种框架,实现代码复用。

低耦合的设计,改变任何一方,不会影响另一方。

低耦合、高内聚-----设计原则

松耦合的设计之所以能够让我们建立有弹性的OO系统,应对变化,便于扩展和维护,就是应为它将对象之间的互相依赖降到了最低。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: