转载请注明出处: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系统,应对变化,便于扩展和维护,就是应为它将对象之间的互相依赖降到了最低。