标签(空格分隔): 设计模式
引言
提起设计模式,观察者模式很多人都不陌生,因为它实在是太常见了,无论是在软件设计中还是在生活中都可以寻找到他的踪迹。其实软件设计就是对现实生活的抽象。
下面我们就来提及一个生活中的现象问题:
广播员在进行广播,远在山区的大大小小的山村的村民正在使用收音机,收听广播。
这是一个现实世界的问题,我们需要用抽象成软件设计模型,
首先,广播员是一个对象,村民使用的收音机呢,也是一个对象,这两个对象之间有什么联系呢?
广播员只要一说话,收音机就能够得到声音响应。这个过程是一个及时的响应的。
那么如何实现这个问题的抽象呢?----->观察者模式
模型抽象
这里我们做一个规范定义:我们将被观察的对象
定义成事件发生者
,将观察的对象,我们定义成观察者
广播模型:
事件发生
者接口
public interface Observable {
//注册广播接收器
void register(Observer observer);
//移除广播接收器
void removeRegister(Observer observer);
//通知更新
void notifyUpdate();
}
观察者
接口
public interface Observer<T extends Observable> {
void update(T t);
}
上面两个接口是最上层抽象接口,首先事件发生者
里要有注册观察者的方法,同时又要移除观察者的方法,然后是同时所有的观察者跟新消息的方法。
在我们的观察者中
呢?很简单,我们就是接收事件发生者
里的消息。
可观察者实现类:
public class ObservableImpl implements Observable{
private List<Observer> list = new ArrayList<>();
@Override
public void register(Observer observer) {
list.add(observer);
}
@Override
public void removeRegister(Observer observer) {
list.remove(observer);
}
@Override
public void notifyUpdate() {
for (Observer observer : list) {
observer.update(this);
}
}
}
上面的事件发生者
实现类,我们可以看到,里面持有了一个观察者
对象的集合,当我们注册一个观察者
的时候,集合就add
一个,移除一个观察者
的时候集合就remove
一个。这个很容易理解,我们的更新的方法是如何实现的呢?我们的结果是通知所有的观察者
,这个很自然的想到是遍历集合中的所有观察者
对象,然后分别通知就行了。
广播实现类:
/**
* 广播器
* @author Sivin
*
*/
public class Broadcast extends ObservableImpl{
private String mMsg;
/**
* 发送消息
* @param msg
*/
public void sendMsg(String msg){
this.mMsg = msg;
notifyUpdate();
}
/**
* 获取消息
* @return
*/
public String getMsg(){
return mMsg;
}
}
简单分析一下,我们的广播实现类:没有什么东西,里面有一个消息变量,然后有一个发送消息的方法,和获取广播消息的方法,很好理解,广播调用发送消息的接口,然后通知所有注册的收音机,确接收消息就行了
/**
* 收音机的类
* @author Sivin
*
*/
public class Radio implements Observer<Broadcast>{
private String mMsg;
public String getMsg(){
return mMsg;
}
@Override
public void update(Broadcast t) {
mMsg = t.getMsg();
}
}
上面的类很容易理解,不用解释了。
好了,我们来测试一下:
public class Test {
public static void main(String[] args) {
//创建广播员:
Broadcast broadcast = new Broadcast();
//创建观察者-->收音机
Radio radio1 = new Radio();
Radio radio2 = new Radio();
Radio radio3 = new Radio();
//注册建立联系
broadcast.register(radio1);
broadcast.register(radio2);
broadcast.register(radio3);
//广播开始广播
broadcast.sendMsg("广播声音--->:123456");
//接收声音
System.out.println("收音机radio1接收到:"+radio1.getMsg());
System.out.println("收音机radio2接收到:"+radio2.getMsg());
System.out.println("收音机radio3接收到:"+radio3.getMsg());
}
}
下面是运行结果:
收音机radio1接收到:广播声音--->:123456
收音机radio2接收到:广播声音--->:123456
收音机radio3接收到:广播声音--->:123456