深入浅出设计模式之策略模式观察者模式

Posted 软件猫

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入浅出设计模式之策略模式观察者模式相关的知识,希望对你有一定的参考价值。

第一章 入门

1.这里讲了一个简单的例子,鸭子的例子。鸭子都会叫,都会走,都会游泳(不变的部分)。但是有的鸭子会飞,有的鸭子的外观不一样等等(变得部分),如何设计呢?采取分离的策略,将不变的部分和可变的部分分离,因此引出我们第一个设计原则:找出应用中可能需要的变化之处,把它们独立出来,不要和哪些不需要变化的代码混在一起。

2.如何设计呢?对于上面的鸭子的例子,我们知道我们要增强我们的代码弹性, 就是说要更容易修改,引出第二个设计原则:针对接口编程,而不是针对实现编程。具体来讲,对于我们鸭子的每个可变行为,比如飞行行为,单独拿出来作为一个接口。如下图


3.接下来,你就应该要整合鸭子的行为了。前面的过程,我们将鸭子的可变行为委托(delegate)给了FlayBehavior和QuackBehavior。具体的做法是让鸭子类持有FlyBehavior和QuackBehavior的两个实例变量,然后写两个方法,比如飞行方法,如下所示

public void performFly() flyBehavior.fly();

这样鸭子就有了自己的飞行行为,我们只需要在实例化这个鸭子的时候,比如在构造函数中初始化对应的飞行和名叫的具体的类即可。


4.第三个设计原则:多用组合,少用继承。

上述就讲述了一个设计模式策略模式,而且是一个多策略模式,有飞行的策略,有名叫的策略,不同的策略下面又有不同的实现。

观察者模式

观察者模式适用于经常变化且需要被监测的对象。课本上举的例子是气象站的一个类WebData,这个Webdata能获得最新的气象数据并及时的更新到三个布告板。布告板也不能仅仅只有3个,知识说现在有三个, 以后可能会有更多的布告板展示其他的数据(可拓展性)。 怎么办呢? 基本的过程呢,我们用一个简单的例子来解释:假设观察者是订阅报纸的人,简称狗,鸭子,猫和老鼠,他们都订阅了某个报社的报纸(假设鸭子还没订阅)。而被订阅的报社呢,是被观察者,就叫他们报社。整体的工作流程如下: 某天,鸭子向报社说,我想订阅一份报纸(鸭子相当观察者了),这个过程称作注册; 报社街道订阅通知,将鸭子添加到自己的订阅列表; 好,现在鸭子也加入到了观察者里面,开始等待报社送报纸(发送通知); 报社印出了新的报纸,并告诉观察者们报纸已经好了;
老鼠不想当观察者了,想订阅另一个报社的报纸,于是老鼠向报社发送请求,然后老鼠离开了,删除了一个观察者。 报社又产生了新的报纸,只不过老鼠已经接收不到通知了。
那么我们基本就了解了观察者模式的工作流程了,那么观察者模式应该具体怎么实现呢?我们来看类图
一定要注意这几个方法,对于被观察者(主题,Subject),registerObserver,RemoveObserver,NotifyObserver,对于观察者,只需要一个update。这是一个松耦合的设计,观察者只需要等待主题的通知,而主题只知道观察者只有一个update 方法。剩下的就比较简单了。你可以写一个Client类,这个类通过持有观察者和被观察者两个接口,不断的向被观察者内部注册观察者或者移除观察者。或者当被观察者需要通知观察者时,由Client调用notifyObservers()方法。
java内部实现了观察者模式,Observervable抽象类负责被观察者,Observer接口负责观察者,如下图所示


java内置的观察者模式必须要经过两步。即当被观察者更新内容后,必须先setChange(),然后才能调用notifyObserver()看下面的代码 观察者
import java.util.Observable;
import java.util.Observer;

public class BlackBoard implements Observer

	@Override
	public void update(Observable o, Object arg) 
		// TODO Auto-generated method stub
		if(o instanceof Teacher)
			Teacher teacher = (Teacher)o;
			System.out.println(teacher.getContent());
		
		
	

被观察者
import java.util.Observable;

public class Teacher extends Observable
	private String content;
	public Teacher()
	
	
	
	public void measurementsChanged()
		setChanged();
		notifyObservers();
	

	public void setContent(String content)
		this.content=content;
		measurementsChanged();
		
	
	public String getContent() 
		// TODO Auto-generated method stub
		return content;
	

客户端:
public class Client 
	
	public static void main(String[] args)
		Teacher t = new Teacher();
		t.addObserver(new BlackBoard());
		t.setContent("Course Content");
//		t.measurementsChanged();
		t.setContent("new Content");
	


总结一下,观察者模式需要以下步骤: 1、创建观察者和被观察者,这里观察者需要有update()方法,被观察者需要有addObserver(),removeObserver(),notifyOverver()方法。甚至还有自己的状态setChange()表示当前数据有没有更新。 2、在被观察者内部注册观察者,这个可以在客户端或者观察者内部甚至被观察者内部执行,都无所谓的。 3、被观察者更新内容,设置setChange(),通知所有客户端notifyObservers()。




以上是关于深入浅出设计模式之策略模式观察者模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式之观察者模式

Android常用设计模式

设计模式之策略模式

设计模式之策略模式

设计模式之策略模式

设计模式之观察者模式