定义:定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
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>();
????}
????
[email protected]
????public void registerObserver(Observer obs) {
????????// TODO Auto-generated method stub
????????if(obs != null){
????????????mObservers.add(obs);
????????}
????}
?
[email protected]
????public void removeObserver(Observer obs) {
????????// TODO Auto-generated method stub
????????if(obs != null){
????????????mObservers.remove(obs);
????????}
????????
????}
?
[email protected]
????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;
????}
?
[email protected]
????public void update() {
????????// TODO Auto-generated method stub
????????print();
????}
?
[email protected]
????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;
????}
[email protected]
????public void print() {
????????// TODO Auto-generated method stub
????????System.out.println("hall print order : " + mOrderCenter.getOrder());
????}
?
[email protected]
????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()方法。
?