23种设计模式之【使用【事件委托】来完善观察者模式】

在这里插入图片描述

package design_pattern.observer.delegate;
import java.lang.reflect.Method;
/**
 * 使用【事件委托】来完善观察者模式
 *  当一个对象的改变会影响想到其它多个对象时,就可以考虑用观察者模式
 * 因为观察者中的‘抽象通知者’还是依赖‘抽象观察者,也就是说,万一没有了抽象观察者这样的接口,
 * 就实现不了相关通知的功能。为了弥补观察者模式的不足,出现了事件委托模式;
 *
 * 委托就是一种引用方法的类型,一旦为委托分配了方法,委托将与该方法具有完全相同的行为。
 * 委托方法的使用可以像其他任何方法一样,具有参数和返回值,委托可以看作是对函数的抽象,是函数的‘类’,
 * 委托的实例将代表一个具体的函数。
 *
 * 一个委托可以搭载多个方法,所有方法被依次唤起。更重要的是,它可以使得委托对象所搭载的方法并不需要属于同一个类。
 * 即:不同的对象可以执行不同的事件【方法】
 *  因为 java 没有直接实现委托的相关类或者方法,因此可以通过反射的方式添加事件来处理委托。
 */
public class Event {

    //要执行方法的对象
    private Object object;
    //要执行的方法名称
    private String methodName;
    //要执行方法的参数
    private Object[] params;
    //要执行方法的参数类型
    private Class[] paramTypes;

    public Object getObject() {
        return object;
    }

    public void setObject(Object object) {
        this.object = object;
    }

    public String getMethodName() {
        return methodName;
    }

    public void setMethodName(String methodName) {
        this.methodName = methodName;
    }

    public Object[] getParams() {
        return params;
    }

    public void setParams(Object[] params) {
        this.params = params;
    }

    public Class[] getParamTypes() {
        return paramTypes;
    }

    public void setParamTypes(Class[] paramTypes) {
        this.paramTypes = paramTypes;
    }

    public Event(){

    }

    public Event(Object object,String methodName,Object...args){
        this.object=object;
        this.methodName=methodName;
        this.params=args;
        contractParamTypes(this.params);
    }

    //根据参数数组生成参数类型数组
    private void contractParamTypes(Object[] params){
        this.paramTypes=new Class[params.length];
        for(int i=0;i<params.length;i++){
            this.paramTypes[i]=params[i].getClass();
        }
    }


    //执行该 对象的该方法
    public void invoke() throws Exception{
        Method method=object.getClass().getMethod(this.getMethodName(), this.getParamTypes());
        if(null==method){
            return;
        }
        method.invoke(this.getObject(), this.getParams());
    }
}
package design_pattern.observer.delegate;
import java.util.ArrayList;
import java.util.List;
/**
 * 定义一个事件处理器
 */
public class EventHandler {
    //使用一个List
    private List<Event> objects;

    public EventHandler(){
        objects=new ArrayList<>();
    }
    //添加某个对象要执行的事件,及需要的参数
    public void addEvent(Object object,String methodName,Object...args){
        objects.add(new Event(object,methodName,args));
    }
    //通知所有的对象执行指定的事件
    public void notifyEvent() throws Exception{
        for(Event e : objects){
            e.invoke();
        }
    }
}
package design_pattern.observer.delegate;
/**
 * 抽象通知者
 */
public abstract class Notifier {
    private String subjectState;
    private EventHandler eventHandler = new EventHandler();

    public EventHandler getEventHandler() {
        return eventHandler;
    }
    public void setEventHandler(EventHandler eventHandler) {
        this.eventHandler = eventHandler;
    }
    public String getSubjectState() {
        return subjectState;
    }
    public void setSubjectState(String subjectState) {
        this.subjectState = subjectState;
    }
    //增加需要监听的类
    public abstract void addObserver(Object object, String methodName, Object...args);
    // 通知方法
    public abstract void notifyObserver();
}
package design_pattern.observer.delegate;
/**
 * 前台通知者
 */
public class SecretaryNotifier extends Notifier {
    public SecretaryNotifier(){
        this.setSubjectState("号外号外,胡汉三回来了!");
    }
    @Override
    public void addObserver(Object object, String methodName, Object... args) {
        System.out.println("有新的同事委托前台小姐姐");
        this.getEventHandler().addEvent(object,methodName,args);
    }
    @Override
    public void notifyObserver() {
        try {
            this.getEventHandler().notifyEvent();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
package design_pattern.observer.delegate;

/**
 * NBA观察者
 */
public class NBAObserver {

    private String name;

    public NBAObserver(String name){
        this.name = name;
    }

    public void closeNBADirectSeeding(String subjectState) {
        System.out.printf("%s %s 关闭NBA直播,继续工作!\n",subjectState,name);
    }
}
package design_pattern.observer.delegate;

/**
 * 股票观察者
 */
public class StockObserver {

    private String name;

    public StockObserver(String name){
        this.name = name;
    }

    public void closeStockMarket(String subjectState) {
        System.out.printf("%s %s 关闭股票行情,继续工作!\n",subjectState, name);
    }
}
/**
 * 测试方法
 */
public class EventTest {

    public static void main(String[] args) {
        //通知者
        Notifier notifier = new SecretaryNotifier();
        //股票观察者
        StockObserver stockObserver = new StockObserver("张三");
        //NBA观察者
        NBAObserver nbaObserver = new NBAObserver("李四");
        //注册观察者
        notifier.addObserver(stockObserver,"closeStockMarket",notifier.getSubjectState());
        notifier.addObserver(nbaObserver,"closeNBADirectSeeding",notifier.getSubjectState());
        //通知观察者
        notifier.notifyObserver();
    }
}

学到了就要教人,赚到了就要给人!
The more I think, the luckier I am.
【越思考,越幸运】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值