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

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

你可能感兴趣的:(设计模式之观察者模式案例学习)