设计模式——观察者模式

观察者模式

当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。

意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。

下面我将实现一个用cglib动态代理实现对一个对类的观察,当该类调用设置的方法后将会触发一个回调

希望大家对jdk1.8的特性有了解比如lamda表达式,因为下面会用到

首先定位一个接口,接口中定义回调方法

public interface Observer {
    void callback();
}

编写一个被观察的对象

public class Subject {
    private String state;

    public String getState() {
        return state;
    }
    public void setState(String state) {
        this.state = state;
    }
}

编写一个事件的注册器

/**
 * 事件注册器
 */
public class EventListeners {
    private static Map<Class<?>, Map<Method, List<Observer>>> events = new HashMap<>();

    public static void addListener(Class<?> subject, Method method, List<Observer> observer) {
        Map<Method, List<Observer>> methodMapMap = events.get(subject);
        if (methodMapMap != null) {
            checkObjectHaveMethodAndPutObserver(subject, method, observer, methodMapMap);
        }else {
            Map<Method,List<Observer>> methedsObservers=new HashMap<>();
            checkObjectHaveMethodAndPutObserver(subject, method, observer, methedsObservers);
            events.put(subject,methedsObservers);
        }
    }

    private static void checkObjectHaveMethodAndPutObserver(Class<?> subject, Method method, List<Observer> observer, Map<Method, List<Observer>> methodMapMap) {
        Arrays.stream(subject.getDeclaredMethods()).forEach(e->{
            if (e.getName().equals(method.getName())){
                methodMapMap.put(method,observer);
            }
        });
    }

    public static void notice(Class<?> object,Method method) {
        Map<Method, List<Observer>> methodListMap = events.get(object);
        if (methodListMap!=null){
            methodListMap.get(method).forEach(e->e.callback());
        }
    }
    public static boolean haveMethodObServer(Class<?> object,Method method){
        Map<Method, List<Observer>> methodListMap = events.get(object);
        if (methodListMap!=null){
            List<Observer> observers = methodListMap.get(method);
            if (observers!=null&&!observers.isEmpty()){
                return true;
            }
        }
        return false;
    }
}

这里我用了一个Map键为Class,值为另外一个Map这个Map键为方法,值为一个回调方法的List集合

创建CGlibProSubject

public class CGlibProSubject implements MethodInterceptor {

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        String typeName = obj.getClass().getTypeName();
        String myClass = typeName.substring(0, typeName.indexOf("$"));
        Class<?> aClass = obj.getClass().getClassLoader().loadClass(myClass);
        if (EventListeners.haveMethodObServer(aClass, method)) {
            EventListeners.notice(aClass, method);
        }
        Object o = proxy.invokeSuper(obj, args);
        return o;
    }
}

测试

public class Test {
    public static void main(String[] args) throws NoSuchMethodException {
        Subject subject = new Subject();
        Method setState = subject.getClass().getMethod("setState", String.class);
        Observer observer=()->System.out.println("调用了该方法!");
        Observer observer2=()->System.out.println("恭喜你又被调用了");
        EventListeners.addListener(Subject.class,setState,Arrays.asList(observer,observer2));
        CGlibProSubject cGlibProSubject = new CGlibProSubject();
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(Subject.class);
        enhancer.setCallback(cGlibProSubject);
        Subject o = (Subject) enhancer.create();
        o.setState("aaa");
        o.getState();
    }
}

结果

调用了该方法!
恭喜你又被调用了

这里的实现可能有点复杂,简单的实现可以百度一下有很多简单的实现,学习设计模式主要是了解思想

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值