1. 程式人生 > >10_1.事件委託

10_1.事件委託

事件委託:把事情交給委託類去辦,需要傳遞要委託的物件,要委託的方法還有及其引數(定義一個類封裝好這些屬性,並儲存在資料結構中,下面就是很好的列子),最後通過反射呼叫獲取例項,並呼叫其方法

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * 事件委託機制
 * 關鍵:
 * 觀察者模式(抽象通知者,具體通知者,抽象觀察者,具體觀察者)
 * 相比觀察者模式,去掉了抽象觀察者,每個具體觀察者並將“更新”方法名改為各自適合的方法名
 * (每個觀察者都有自己的方法,但引數型別一定要引用型別),主題或抽象通知者
 * 新增Object物件,MethodName方法名,args引數列表(新增具體觀察者)
 * 具體主題或者具體通知者實現通知方法(迴圈呼叫每個具體觀察者:通過反射)
 * @author zbl
 *
 */

public class NotifyCustomer {
    public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        Notifier notifier = new ConcreteNotifier();
        notifier.addListener(new Observer1(), "watch", "lala",true,14);
        notifier.addListener(new Observer2(), "see", "vvvv",12);
        notifier.mynotity();
    }
}

//抽象通知者
interface Notifier{
    public EventHanlder eventHanlder = new EventHanlder();//委託事件交給這個類去辦
    public void addListener(Object object,String methodName,Object...args);//新增監聽者
    public void mynotity() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException;
}

//具體通知者
class ConcreteNotifier implements Notifier{

    @Override
    public void addListener(Object object, String methodName, Object... args) {
        this.eventHanlder.add(object,methodName,args);
    }
    @Override
    public void mynotity() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        //觀察者模式這裡是迴圈抽象觀察者,並呼叫update方法
        //此處用事件委託類,幫忙處理
        this.eventHanlder.mynotity();
    }

}

//事件處理器
class EventHanlder{

    private List<MyEvent> eventList = new ArrayList<MyEvent>();
    
    public void add(Object object, String methodName, Object[] args) {
        //把物件轉換為我的事件
        MyEvent event = new MyEvent(object,methodName,args);
        eventList.add(event);
    }

    public void mynotity() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        for(MyEvent event : eventList){
            event.invoke();
        }
    }
}

//事件
class MyEvent{
    private Object object;
    private String methodName;
    private Object[] args;
    private Class[] paramTypes;
    public MyEvent(Object object, String methodName, Object[] args) {
        this.object = object;
        this.methodName = methodName;
        this.args = args;
        this.paramTypes = this.convertParamTypes(args);
    }
    
    //將引數的型別遍歷出來放入Class類集合中,為反射做準備
    private Class[] convertParamTypes(Object[] args) {
        Class[] clazzes = new Class[args.length];
        for(int i=0;i<args.length;i++){
            clazzes[i] = args[i].getClass();
        }
        return clazzes;
    }
    
    public void invoke() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        //傳入方法名,引數型別
        Method method = object.getClass().getMethod(methodName, paramTypes);
        //傳入物件,引數
        method.invoke(object, args);
    }
}

//具體觀察者1
class Observer1{
    public void watch(String name,Boolean flag,Integer age){
        System.out.println("xixiix:"+name+flag+age);
    }
}
//具體觀察者2
class Observer2{
    public void see(String name,Integer age){
        System.out.println("哈哈:"+name+"---age:"+age);
    }
}