大话设计模式之观察者模式

不知道大家有没有听说过观察者模式,有人也叫发布-订阅模式,我们先来看一个案例,案例如下:一个公司有前台人员,和后台开发人员,公司老板回来的时候会先经过前台然后才来到后台开发这边,工作压力大,后台开发人员偶尔会偷偷懒,炒一下股或者看看NBA这些小工作,他们串通前台的人员,如果老板回来要先通知他们,好让他们有个准备。程序实现如下:

第一步:我们把前台人员称为通知者,我们抽象通知者,因为通知者可能是前台人员或者其他人,但是具有相同的行为,于是可以使用接口来规范行为。

//抽象通知者
public interface Subject {
	
	//添加
	public void attach(Observer observer);
	
	//通知所有的观察者
	public void notifyAllObserver();

}
第二步:前台人员是具体的通知者,实现接口Subject,有三个私有属性,姓名,自己的状态,以及需要通知的观察者,我们把后台开发人员称为观察者,他们可能在看NBA,或者看篮球等等。当老板回来的时候,通知者需要改变自己的状态,通知所有的观察者对象,当然通知者肯定有添加观察者的方法,就是添加需要通知的观察者,这里有两个具体的通知者,一个是前台人员,一个是老板,我们都不希望是老板来通知我们~~
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

//抽象通知者
public class Secretary implements Subject {
	
	private String name;  //姓名
	private String action; //状态
	private List<Observer> observers = new ArrayList<Observer>(); //观察者集合
	
	//添加
	public void attach(Observer observer) {
		observers.add(observer);
	}
	
	//通知所有的观察者
	public void notifyAllObserver() {
		for (Iterator<Observer> iter=observers.iterator(); iter.hasNext();) {
			Observer observer = iter.next();
			observer.update();
		}
	}

	public String getAction() {
		return action;
	}

	public void setAction(String action) {
		this.action = action;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

//通知者
public class Boss implements Subject{
	
	private String name;  //姓名
	private String action; //状态
	private List<Observer> observers = new ArrayList<Observer>(); //观察者集合
	
	//添加
	public void attach(Observer observer) {
		observers.add(observer);
	}
	
	//通知所有的观察者
	public void notifyAllObserver() {
		for (Iterator<Observer> iter=observers.iterator(); iter.hasNext();) {
			Observer observer = iter.next();
			observer.update();
		}
	}

	public String getAction() {
		return action;
	}

	public void setAction(String action) {
		this.action = action;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
}
第三步:抽象观察者,因为我们知道观察者有各种各样的,在做什么事情,我们都不知道,但是老板回来,我们就需要通知他们。
于是我使用抽象类来定义,而不使用接口,因为抽象类可以有属性,即是状态数据字段,定义一个抽象的方法,就是更新自己的状态,也有一个通知者的引用,进而和通知者联系。
//抽象观察者	
public abstract class Observer {
	
	protected String name;  //姓名
	protected Secretary secretary; //通知者

	//constructor
	public Observer(String name, Secretary secretary) {
		this.name = name;
		this.secretary = secretary;
	}
	
	//更新状态
	public abstract void update();
	
}
第四步:我们来两个具体的观察者,一个在看NBA,一个在炒股。

//NBA观察者	
public class NBAObserver extends Observer{
	
	public NBAObserver(String name, Secretary secretary) {
		super(name, secretary);
	}

	//更新状态
	public void update() {
		System.out.println(secretary.getAction() + " " + this.name + "不要看篮球了,继续工作。");
	}
}
//股票观察者	
public class StockObserver extends Observer{
	
	public StockObserver(String name, Secretary secretary) {
		super(name, secretary);
	}

	//更新状态
	public void update() {
		System.out.println(secretary.getAction() + " " + this.name + "关闭股票行情,继续工作。");
	}
}
第五步:接下来就是测试一下了。我们定义一个通知者、两个观察者,通知者是老板,老板回来的时候通知我们的两个观察者,很糟糕哦~~
//测试
/**
 * 分析:我们使用继承与多态的方式重构了程序,抽象了观察者和通知者,因为观察者可能是在看NBA,
 * 也可能在看股票或者其他,而通知者也一样,可能是老板,也可能是是我们上司,但是通知者具有相
 * 同的行为,于是可以使用接口来定义抽象,使用依赖倒置的原则,可以使得程序的可拓展性大大提高
 * ,代码的可重用性也提高。
 */
public class Test2 {
	
	public static void main(String[] args) {
		Secretary boss = new Secretary(); //通知者
		Observer xiaowang = new StockObserver("小王", boss); //股票玩家
		Observer xiaodong = new NBAObserver("小东", boss); //股票玩家
		
		//通知者记录
		boss.attach(xiaowang);
		boss.attach(xiaodong);
		
		//通知者状态发生改变
		boss.setAction("老板我回来了!");
		
		//通知所有的观察者即股票玩家
		boss.notifyAllObserver();
	}
	
}
总结:

观察者模式也叫发布-订阅模式。定义:观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象 。这个主题对象在状态发生变化的时,会通知所有的观察者对象,使它们能够自动的更新自己。

遵循的原则:依赖倒置的原则、里氏替换原则。

特点:将一个系统分隔成一系列相互协作的类有一个很不好的副作用,那就是需要维护相互对象将的一致性,我们不希望为了维护一致性而是各类紧密相连,这样会给维护、扩展和重用都带来不便。

使用场景:1.当一个对象改变时需要同时改变其他对象的时候。(不需要知道具体需要改变的对象)







  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值