您的位置:首页 > 其它

3_观察者模式

2018-01-14 20:49 148 查看
写在前面:设计模式不是干掉变化,而是让变化集中到一个区域,方便开发。

观察者模式就是现实生活情景的一个写真。在现实生活中有这样一个场景,就是在医院等待检查报告,等待的病人或者家属怎么知道报告已经出来了呢?有两种解决方案:

1、 每个病人或者家属每隔一段时间就去问,护士就根据已经出来的报告进行回答,这样就搞定了。

2、 每个病人或者家属都坐着等,护士每拿到一份报告就喊报告上面病人的名字,病人或者家属都可以听到护士叫的名字,然后做出相应的回应。

方案一明显的缺点就是病人需要不停的问,护士需要不停的回答,而且当新的报告出来了,病人无法第一时间知道。病人费劲,护士费劲,消息还不够灵通。

方案二的优点就是省事且高效,生活常识,不在赘述。把方案二映射到代码中就是所谓的观察者模式。

 

方案二在代码中的映射:

护士需要做三件事:1、登记病人的信息;2、接收到新的报告后喊病人的名字;3、删除登记的名字。

病人需要做一件事:听到护士的呼叫之后就作出相应的反应。

接下来的代码就是简单了。

 import java.util.ArrayList;
import java.util.List;

public class ObserverTest1 {
public static void main(String[] args) {
//需要一个护士站
ISubject station = new NurseStation();

//需要几个病人
Patient patient1 = new Patient("张三");
Patient patient2 = new Patient("李四");
Patient patient3 = new Patient("王五");

//病人需要在护士站登记一下
station.addObserver(patient3);
station.addObserver(patient2);
station.addObserver(patient1);

//新报告来了,护士叫名字
station.notifyObserver("李四");
station.notifyObserver("王五");

//病人拿走报告,删除登记的名字
station.removeObserver(patient2);
station.removeObserver(patient3);
}
}

/**
* 将护士站的工作抽象出来,便于扩展
*/
interface ISubject {
//登记信息
void addObserver(IObserver observer);

//通知登记的观察者
void notifyObserver(String name);

//病人离开 删除名字
void removeObserver(IObserver observer);
}

/**
* 将病人的工作抽象为Observer,便于扩展
*/
interface IObserver {
void update(String name);
}

/**
* 护士站 做三件事
* 1、登记病人的信息;
* 2、接收到新的报告后喊病人的名字;
* 3、删除登记的名字。
*/
class NurseStation implements ISubject {

//护士需要一个本子做记录 用list
private List<IObserver> patients = new ArrayList<IObserver>();

// 病人来登记
public void addObserver(IObserver observer) {
patients.add(observer);
}

//新的报告出来了 护士喊一嗓子,所有的病人都可以听见
public void notifyObserver(String name) {
for (IObserver patient : patients) {
patient.update(name);
}
}

//病人离开、删除登记的名字。
public void removeObserver(IObserver observer) {
patients.remove(observer);
}
}

class Patient implements IObserver {
//病人的名字
private String name;

public Patient(String name) {
this.name = name;
}

//听到护士叫的名字,作出对应的反应
public void update(String name) {
if (name != null && name.equals(this.name)) {
System.out.println("我是" + name + ",我去拿报告。");
} else {
System.out.println("我是" + this.name + ",叫的是" + name + ",继续等着。");
}
}
}

/**
* 结果
* 我是王五,叫的是李四,继续等着。
* 我是李四,我去拿报告。
* 我是张三,叫的是李四,继续等着。
* 我是王五,我去拿报告。
* 我是李四,叫的是王五,继续等着。
* 我是张三,叫的是王五,继续等着。
*/

 

最后我们分析一下这种模式对变化的“驱赶”:

1、“病人(观察者)”的增加与减少与“护士站(被观察者)”无关;

2、接收消息和发送消息只和“护士站(被观察者)”有关,而且可以快速通知。

 

关于观察者模式,一个经典的例子就是Android中的Button的消息机制,大家有兴趣可以去看看。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  观察者模式