常用设计模式之观察者模式 + 事件委托

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 -- 观察者模式

C# 委托和事件 与 观察者模式(发布-订阅模式)讲解 by天命

观察者模式与事件委托

观察者设计模式 Vs 事件委托(java)

事件委托实现观察者模式

利用事件委托弥补观察者模式不足