转载请注明出处: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(); }
public interface Observer { public void update(Observable o,Object obj); }
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+"只老鼠"; } } }
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); } } }
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); } } }
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; } }
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系统,应对变化,便于扩展和维护,就是应为它将对象之间的互相依赖降到了最低。