常用设计模式之观察者模式 + 事件委托
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了常用设计模式之观察者模式 + 事件委托相关的知识,希望对你有一定的参考价值。
常用设计模式之观察者模式 + 事件委托
-
作用及UML
(摘自《大话设计模式》)
-
Code
1 abstract class Subject{ 2 protected String state; 3 public void setState(String state){this.state = state;} 4 public String getState(){return this.state;} 5 6 private List<Observer> observers = new ArrayList<Observer>(); 7 public void attach(Observer o){observers.add(o);} 8 public void detach(Observer o){observers.remove(o);} 9 public void notifyObservers(){ 10 for( Observer o : observers ){ 11 o.update(); 12 } 13 } 14 } 15 class ConcreteSubject extends Subject{ 16 17 public ConcreteSubject(String state){ 18 super.state = state; 19 } 20 } 21 interface Observer{ 22 void update(); 23 } 24 class ConcreteObserver implements Observer{ 25 private String name; 26 private String state; 27 private Subject subject; 28 public ConcreteObserver(Subject subject, String name){ 29 this.subject = subject; 30 this.name = name; 31 } 32 public void update(){ 33 this.state = subject.getState(); 34 System.out.println("观察者"+name+"的状态改为"+this.state); 35 } 36 } 37 public class ObserverTest{ 38 public static void main(String[] args){ 39 Subject s = new ConcreteSubject("happy"); 40 Observer o1 = new ConcreteObserver(s, "1"); 41 Observer o2 = new ConcreteObserver(s, "2"); 42 s.attach(o1); 43 s.attach(o2); 44 s.notifyObservers(); 45 s.setState("sad"); 46 s.detach(o2); 47 s.notifyObservers(); 48 } 49 } 50 51 /*out: 52 观察者1的状态改为happy 53 观察者2的状态改为happy 54 观察者1的状态改为sad 55 */
Event Delegation (事件委托)
-
UML-1
-
Code-1
1 class Event{ 2 //要执行方法的对象 3 private Object object; 4 //要执行的方法名称 5 private String methodName; 6 //要执行方法的参数 7 private Object[] params; 8 //要执行方法的参数类型 9 private Class[] paramTypes; 10 11 public Event(Object object, String methodName, Object...args){ 12 this.object = object; 13 this.methodName = methodName; 14 this.params = args; 15 this.paramTypes = getParamTypes(args); 16 } 17 18 //根据参数数组生成参数类型数组 19 private Class[] getParamTypes(Object[] params){ 20 if(params==null || params.length==0) 21 return null; 22 Class[] types = new Class[params.length]; 23 for( int i=0, len=params.length; i < len; i++ ){ 24 types[i] = params[i].getClass(); 25 } 26 return types; 27 } 28 29 public void invoke() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException 30 { 31 Method method = this.object.getClass().getMethod(this.methodName, this.paramTypes); 32 method.invoke(this.object, this.params); 33 } 34 } 35 //class EventList{ 36 class EventHandler{ 37 private List<Event> events = new ArrayList<Event>(); 38 39 public void addEvent(Object object, String methodName, Object...args){ 40 events.add(new Event(object, methodName,args)); 41 } 42 43 public void removeEvent(Event event){ 44 events.remove(event); 45 } 46 47 public void handle() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException 48 { 49 for( Event e : events ){ 50 e.invoke(); 51 } 52 } 53 } 54 interface Notifier{ 55 void addListener(Object object, String methodName, Object...args); 56 void notifyAllObservers() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException; 57 } 58 class ConcreteNotifier implements Notifier { 59 protected EventHandler handler = new EventHandler(); 60 public void addListener(Object object, String methodName, Object...args){ 61 handler.addEvent(object, methodName, args); 62 } 63 public void notifyAllObservers() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException 64 { 65 handler.handle(); 66 } 67 } 68 class ConcreteObserverA { 69 public void play(String ball){ 70 System.out.println("---------play" + ball); 71 } 72 } 73 class ConcreteObserverB { 74 public void watchTV(){ 75 System.out.println("---------watchTV---------"); 76 } 77 } 78 public class EventDelegationTest 79 { 80 public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException 81 { 82 Notifier notifier = new ConcreteNotifier(); 83 ConcreteObserverA a = new ConcreteObserverA(); 84 ConcreteObserverB b = new ConcreteObserverB(); 85 notifier.addListener(a, "play", " BasketBall"); 86 notifier.addListener(b, "watchTV" ); 87 notifier.notifyAllObservers(); 88 } 89 }
-
UML-2
-
Code-2
1 class Event{ 2 //要执行方法的对象 3 private Object object; 4 //要执行的方法名称 5 private String methodName; 6 //要执行方法的参数 7 private Object[] params; 8 //要执行方法的参数类型 9 private Class[] paramTypes; 10 11 public Event(Object object, String methodName, Object...args){ 12 this.object = object; 13 this.methodName = methodName; 14 this.params = args; 15 this.paramTypes = getParamTypes(args); 16 } 17 18 //根据参数数组生成参数类型数组 19 private Class[] getParamTypes(Object[] params){ 20 if(params==null || params.length==0) 21 return null; 22 Class[] types = new Class[params.length]; 23 for( int i=0, len=params.length; i < len; i++ ){ 24 types[i] = params[i].getClass(); 25 } 26 return types; 27 } 28 29 public void invoke() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException 30 { 31 Method method = this.object.getClass().getMethod(this.methodName, this.paramTypes); 32 method.invoke(this.object, this.params); 33 } 34 } 35 interface Notifier{ 36 void addListener(Object object, String methodName, Object...args); 37 void notifyAllObservers() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException; 38 } 39 class ConcreteNotifier implements Notifier { 40 private List<Event> events = new ArrayList<Event>(); 41 public void addListener(Object object, String methodName, Object...args){ 42 events.add(new Event(object, methodName,args)); 43 } 44 public void removeListener(Event event){ 45 events.remove(event); 46 } 47 public void notifyAllObservers() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException 48 { 49 for( Event e : events ){ 50 e.invoke(); 51 } 52 } 53 } 54 class ConcreteObserverA { 55 public void play(String ball){ 56 System.out.println("---------play" + ball); 57 } 58 } 59 class ConcreteObserverB { 60 public void watchTV(){ 61 System.out.println("---------watchTV---------"); 62 } 63 } 64 public class EventDelegationTest 65 { 66 public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException 67 { 68 Notifier notifier = new ConcreteNotifier(); 69 ConcreteObserverA a = new ConcreteObserverA(); 70 ConcreteObserverB b = new ConcreteObserverB(); 71 notifier.addListener(a, "play", " BasketBall"); 72 notifier.addListener(b, "watchTV" ); 73 notifier.notifyAllObservers(); 74 } 75 }
以上是关于常用设计模式之观察者模式 + 事件委托的主要内容,如果未能解决你的问题,请参考以下文章
《C#零基础入门之百识百例》(七十八)委托事件实例练习3 -- 观察者模式