浅谈java中内置的观察者模式与动态代理的实现

一.关于观察者模式

1.将观察者与被观察者分离开来,当被观察者发生变化时,将通知所有观察者,观察者会根据这些变化做出对应的处理。

2.jdk里已经提供对应的Observer接口(观察者接口)与Observable(被观察者类)用于实现观察者模式

3.关于Observer接口,该接口只有一个update方法,当被观察者发生相关变化时,会通知所有的观察者,观察者接受到通知时,调用update方法进行处理。贴出源代码:

  View Code

4:关于被观察者Observable的常用方法:

    1.  public synchronized void addObserver(Observer o);//添加观察者对象

    2. public void notifyObservers();//通知所有观察者

    3. protected synchronized void setChanged();//设置观察项已经做出改变,此方法很重要

贴出源代码,注意内部实现:

  View Code

5.举一个例子吧:当婴儿哭泣时,则通知家人来哄宝宝,那么这里很明显婴儿是一个被观察者,当婴儿哭泣时,立刻通知家人(观察者)

复制代码
package com.bdqn.s2.javaoop.study.proxy;

import java.lang.reflect.Proxy;
import java.util.Observable;
import java.util.Observer;

/**
 * 婴儿类,被观察者
 */
public class Baby extends Observable {

    private int hungry;

    private String name;


    public String getName() {
        return name;
    }

    public Baby(String name, int hungry) {
        this.hungry = hungry;
        this.name = name;
        addObserver(new Parents());//添加观察者对象,需要家长监管
    }

    /**
     * 婴儿开始哭泣
     */
    public void cry() {
        if (hungry < 100) {
            System.out.printf("baby%s饿了,开始哭泣...%n", name);
            setChanged();//饥饿值过低,触发变化,此方法必须被调用
            notifyObservers();//通知观察者
        }
    }
}

/**
 * 家长,观察者
 */
class Parents implements Observer {
    @Override
    public void update(Observable o, Object arg) {

        if (o instanceof Baby) {
            Baby baby = (Baby) o;
            System.out.println(baby.getName()+"开始哭泣,赶紧哄宝宝啦");
        }
    }

}

public class Main {

    public static void main(String[] args) {
        Baby baby = new Baby("豆豆",9);
        baby.cry();
    }
}

/*
输出结果
baby豆豆饿了,开始哭泣...
豆豆开始哭泣,赶紧哄宝宝啦
*/
复制代码

 

扫描二维码关注公众号,回复: 2170002 查看本文章

二 关于动态代理模式

1)代理模式是设计模式中非常常见的一种模式,这种模式可以实现对原有方法的扩展,举个例子经纪人可以替明星们办理一些事情,那么此时经纪人可以视为明星的代理。

2)代理模式可以分为静态代理和动态代理,在这里我们只对JDK提供的动态代理进行讨论。

3)由于JDK提供的代理模式所代理的类继承了Proxy,因此我们只能接口进行代理,针对类的代理可以自行参考cglib框架 

4)InvocationHandler:是代理实例的调用处理程序 实现的接口。 每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的 invoke 方法。

//proxy:代理类,method:代理执行的方法 args:方法参数
public Object invoke(Object proxy, Method method, Object[] args);

5)Proxy:该类主要是获取或者新创建动态代理对象

//该方法主要用于获取代理对象,注意一定是针对接口进行代理 
public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException

6)针对上述例子进行改造:添加保姆类并改造Baby类的构造方法:

复制代码
package com.bdqn.s2.javaoop.study.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Observer;

/**
 * 保姆类
 */
public class Nanny implements InvocationHandler {

    private Observer parents;

    public Nanny(){
        parents = new Parents();
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("保姆开始照顾孩子");
        Object object = method.invoke(parents, args);
        return object;
    }
}
复制代码

Baby类构造函数改造:

public Baby(String name, int hungry) {
        this.hungry = hungry;
        this.name = name;
        addObserver((Observer) Proxy.newProxyInstance(Baby.class.getClassLoader(),new Class[]{Observer.class},new Nanny()));
    }

输出结果:

baby豆豆饿了,开始哭泣...
保姆开始照顾孩子
豆豆开始哭泣,赶紧哄宝宝啦

 郑州男科医院:http://www.zztongjiyiyuan.com/郑州男性医院哪家好:http://www.zztongjiyiyuan.com/郑州专业男科医院【挂号】:http://www.zztongjiyiyuan.com/郑州好的男科医院:http://www.zztongjiyiyuan.com/郑州哪家医院看男科好:http://www.zztongjiyiyuan.com/郑州专业男科医院:http://www.zztongjiyiyuan.com/郑州男科医院哪里好:http://www.zztongjiyiyuan.com/https://yyk.familydoctor.com.cn/12248/

猜你喜欢

转载自blog.csdn.net/qq_42606051/article/details/81041564