GoF23种设计模式之行为型模式之观察者模式

一、概述
        定义对象之间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
二、适用性
1.当一个抽象模型有两个方面,其中一个方面依赖于另一方面的时候。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
2.当对一个对象的改变需要同时改变其它对象,而且不知道具体有多少对象需要改变的时候。
3.当一个对象必须通知其它对象,而它又不能假定其它对象是谁的时候。
三、参与者
1.Subject(目标):目标知道它的观察者。可以有任意多个观察者观察同一个目标。提供注册和删除观察者对象的接口。
2.Observer(观察者):为那些在目标发生改变时需要获得通知的对象定义一个更新接口。
3.ConcreteSubject(具体目标):将有关状态存入各ConcreteObserver对象。当它的状态发生改变时,向它的各个观察者发出通知。
4.ConcreteObserver(具体观察者):维护一个指向ConcreteSubject对象的引用。存储有关状态,这些状态应与目标的状态保持一致。实现Observer的更新接口以使自身状态与目标的状态保持一致。

四、类图

五、示例

Subject

[java] view plain copy
 
 print?
  1. package cn.lynn.observer;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. public abstract class Citizen {  
  7.   
  8.     protected List<Policeman> polices;  
  9.   
  10.     private String action = "normal";  
  11.   
  12.     public String getAction() {  
  13.         return action;  
  14.     }  
  15.   
  16.     public void setAction(String action) {  
  17.         this.action = action;  
  18.     }  
  19.   
  20.     public void setPolices() {  
  21.         polices = new ArrayList<Policeman>();  
  22.     }  
  23.   
  24.     public void register(Policeman police) {  
  25.         polices.add(police);  
  26.     }  
  27.   
  28.     public void unregister(Policeman police) {  
  29.         polices.remove(police);  
  30.     }  
  31.   
  32.     public abstract void notify(String action);  
  33. }  

Observer

[java] view plain copy
 
 print?
  1. package cn.lynn.observer;  
  2.   
  3. public interface Policeman {  
  4.   
  5.     public void setOut(Citizen citizen);  
  6.   
  7. }  

ConcreteSubject

[java] view plain copy
 
 print?
  1. package cn.lynn.observer;  
  2.   
  3. public class DongHuCitizen extends Citizen {  
  4.   
  5.     public DongHuCitizen(Policeman police) {  
  6.         setPolices();  
  7.         register(police);  
  8.     }  
  9.   
  10.     @Override  
  11.     public void notify(String action) {  
  12.         setAction(action);  
  13.         for (int i = 0; i < polices.size(); i++) {  
  14.             Policeman police = polices.get(i);  
  15.             police.setOut(this);  
  16.         }  
  17.     }  
  18.   
  19. }  
[java] view plain copy
 
 print?
  1. package cn.lynn.observer;  
  2.   
  3. public class NanHuCitizen extends Citizen {  
  4.   
  5.     public NanHuCitizen(Policeman police) {  
  6.         setPolices();  
  7.         register(police);  
  8.     }  
  9.   
  10.     @Override  
  11.     public void notify(String action) {  
  12.         setAction(action);  
  13.         for (int i = 0; i < polices.size(); i++) {  
  14.             Policeman police = polices.get(i);  
  15.             police.setOut(this);  
  16.         }  
  17.     }  
  18.   
  19. }  

ConcreteObserver

[java] view plain copy
 
 print?
  1. package cn.lynn.observer;  
  2.   
  3. public class DongHuPoliceman implements Policeman {  
  4.   
  5.     @Override  
  6.     public void setOut(Citizen citizen) {  
  7.         String action = citizen.getAction();  
  8.         if(action.equals("normal")) {  
  9.             System.out.println("行为一切正常");  
  10.         } else if(action.equals("unnormal")) {  
  11.             System.out.println("有偷窃行为,东湖警察出动!");  
  12.         }  
  13.     }  
  14.   
  15. }  
[java] view plain copy
 
 print?
  1. package cn.lynn.observer;  
  2.   
  3. public class NanHuPoliceman implements Policeman {  
  4.   
  5.     @Override  
  6.     public void setOut(Citizen citizen) {  
  7.         String action = citizen.getAction();  
  8.         if(action.equals("normal")) {  
  9.             System.out.println("行为一切正常");  
  10.         } else if(action.equals("unnormal")) {  
  11.             System.out.println("有抢劫行为,南湖警察出动!");  
  12.         }  
  13.     }  
  14.   
  15. }  

Client

[java] view plain copy
 
 print?
  1. package cn.lynn.observer;  
  2.   
  3. public class Client {  
  4.   
  5.     public static void main(String[] args) {  
  6.         Policeman dhPolice = new DongHuPoliceman();  
  7.         Policeman nhPolice = new NanHuPoliceman();  
  8.   
  9.         Citizen citizen = new DongHuCitizen(dhPolice);  
  10.         citizen.notify("normal");  
  11.         citizen.notify("unnormal");  
  12.   
  13.         citizen = new NanHuCitizen(nhPolice);  
  14.         citizen.notify("normal");  
  15.         citizen.notify("unnormal");  
  16.     }  
  17. }  

Result

[java] view plain copy
 
 print?
    1. 行为一切正常  
    2. 有偷窃行为,东湖警察出动!  
    3. 行为一切正常  
    4. 有抢劫行为,南湖警察出动!  
posted @ 2017-09-03 22:37  皇问天  阅读(293)  评论(0编辑  收藏  举报