设计模式-观察者
定义:定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
UML图示:
代码示例:就拿之前做过的项目举例,博主要实现餐厅打印订单的功能,如下图示。
通过上图很明显我们发现订单中心与打印机存在一对多的关系,根据上面对于观察者定义,采用观察者模式,可以让订单中心的状态改变的同时,让所有打印机都接收到状态的改变。下面我们再来看一张UML图。
定义Subject接口
public interface Subject {
public void registerObserver(Observer obs);
public void removeObserver(Observer obs);
public void notifyObervers();
}
定义订单中心,实现Subject接口
public class OrderCenter implements Subject{
private ArrayList<Observer> mObservers = null;
private String order = null;
public OrderCenter() {
// TODO Auto-generated constructor stub
mObservers = new ArrayList<Observer>();
}
@Override
public void registerObserver(Observer obs) {
// TODO Auto-generated method stub
if(obs != null){
mObservers.add(obs);
}
}
@Override
public void removeObserver(Observer obs) {
// TODO Auto-generated method stub
if(obs != null){
mObservers.remove(obs);
}
}
@Override
public void notifyObervers() {
// TODO Auto-generated method stub
if(mObservers != null && mObservers.size() > 0){
for(Observer obs : mObservers)
obs.update();
}
}
public void setOrder(String order){
this.order = order;
notifyObervers();
}
public String getOrder(){
return order;
}
}
定义打印接口
public interface Print {
public void print();
}
定义观察者接口
public interface Observer {
public void update();
}
前台打印机,实现打印,观察者接口
public class ReceptionPrint implements Print,Observer{
private OrderCenter mOrderCenter = null;
public ReceptionPrint(OrderCenter oc) {
// TODO Auto-generated constructor stub
mOrderCenter = oc;
}
@Override
public void update() {
// TODO Auto-generated method stub
print();
}
@Override
public void print() {
// TODO Auto-generated method stub
System.out.println("reception print order : " + mOrderCenter.getOrder());
}
}
大堂打印机,实现打印,观察者接口
public class HallPrint implements Observer,Print{
private OrderCenter mOrderCenter = null;
public HallPrint(OrderCenter oc) {
// TODO Auto-generated constructor stub
mOrderCenter = oc;
}
@Override
public void print() {
// TODO Auto-generated method stub
System.out.println("hall print order : " + mOrderCenter.getOrder());
}
@Override
public void update() {
// TODO Auto-generated method stub
print();
}
}
测试代码
public class Main {
public static void main(String[] args) {
OrderCenter oc = new OrderCenter();
Observer hallObser = new HallPrint(oc);
Observer receptionObser = new ReceptionPrint(oc);
oc.registerObserver(hallObser);
oc.registerObserver(receptionObser);
oc.setOrder("take out order!");
oc.removeObserver(receptionObser);
oc.setOrder("hall order");
}
}
测试结果
hall print order : take out order!
reception print order : take out order!
hall print order : hall order
上面我们自己定义了观察者和主题的接口,其实在JDK类包java.util包含最基础的Observer接口和Observable类,和我们定义的接口几乎一样,你甚至可以通过notifyObservers()或notifyObservers(Object arg)方法,选择pull或者push的方式让观察者获取数据。注意调研notifyObservers前先调用setChanged()方法。
浙公网安备 33010602011771号