美文网首页
设计模式之观察和代理

设计模式之观察和代理

作者: xbmchina | 来源:发表于2018-12-18 23:04 被阅读0次

    1.观察者模式

    其实就是发布订阅模式,发布者发布信息,订阅者获取信息,订阅了就能收到信息,没订阅就收不到信息。

    • 1.1 抽象被观察者角色:也就是一个抽象主题,它把所有对观察者对象的引用保存在一个集合中,每个主题都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类和接口来实现。
    • 1.2 抽象观察者角色:为所有的具体观察者定义一个接口,在得到主题通知时更新自己。
    • 1.3 具体被观察者角色:也就是一个具体的主题,在集体主题的内部状态改变时,所有登记过的观察者发出通知。
    • 1.4 具体观察者角色:实现抽象观察者角色所需要的更新接口,一边使本身的状态与制图的状态相协调。
    public interface Subject {
    
        /*增加观察者*/
        public void add(Observer observer);
    
        /*删除观察者*/
        public void del(Observer observer);
    
        /*通知所有的观察者*/
        public void notifyObservers();
    
        /*自身的操作*/
        public void operation();
    
    }
    
    
    public abstract class AbstractSubject implements Subject {
    
        private Vector<Observer> vector = new Vector<>();
    
        @Override
        public void add(Observer observer) {
            vector.add(observer);
        }
    
        @Override
        public void del(Observer observer) {
            vector.remove(observer);
        }
    
        @Override
        public void notifyObservers() {
            Enumeration<Observer> enumeration = vector.elements();
            while (enumeration.hasMoreElements()){
                enumeration.nextElement().update();
            }
        }
    }
    
    
    public interface Observer {
        public void update();
    }
    
    public class Observer1 implements Observer {
        @Override
        public void update() {
            System.out.println("observer1 have received!");
        }
    }
    
    public class Observer2 implements Observer {
        @Override
        public void update() {
            System.out.println("observer2 has received");
        }
    }
    
    public class Test {
    
        public static void main(String[] args) {
            Subject sub = new MySubject();
            sub.add(new Observer1());
            sub.add(new Observer2());
    
            sub.operation();
        }
    }
    
    

    2.代理模式

    代理模式的定义:代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。通俗的来讲代理模式就是我们生活中常见的中介。

    举个例子来说明:假如说我现在想买一辆二手车,虽然我可以自己去找车源,做质量检测等一系列的车辆过户流程,但是这确实太浪费我得时间和精力了。我只是想买一辆车而已为什么我还要额外做这么多事呢?于是我就通过中介公司来买车,他们来给我找车源,帮我办理车辆过户流程,我只是负责选择自己喜欢的车,然后付钱就可以了。

    2.1. 分类
    • 静态代理是创建或特定工具自动生成源代码,在对其编译。在程序运行之前,代理类.class文件就已经被创建了。
    • 动态代理是在程序运行时通过反射机制动态创建的。
    2.2. 静态代理实现
    public interface Sourceable {
        public void method();
    }
    
    public class Source implements Sourceable {
        @Override
        public void method() {
            System.out.println("the original method!");
        }
    }
    
    public class Proxy implements Sourceable {
    
        private Source source;
    
        public Proxy() {
            super();
            this.source = new Source();
        }
    
        @Override
        public void method() {
            before();
            source.method();
            atfer();
        }
    
        private void atfer() {
            System.out.println("after proxy!");
        }
        private void before() {
            System.out.println("before proxy!");
        }
    }
    
    
    public class Test {
    
        public static void main(String[] args) {
            Sourceable sourceable = new Proxy();
            sourceable.method();
        }
    }
    
    
    2.3. 动态代理实现(JDK)
    public class DynamicProxyHandler implements InvocationHandler {
    
        private Object object;
    
        public DynamicProxyHandler(final Object object) {
            this.object = object;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("买房前准备");
            Object result = method.invoke(object, args);
            System.out.println("买房后装修");
            return result;
        }
    }
    
    public class DynamicProxyTest {
        public static void main(String[] args) {
            BuyHouse buyHouse = new BuyHouseImpl();
            BuyHouse proxyBuyHouse = (BuyHouse) Proxy.newProxyInstance(BuyHouse.class.getClassLoader(), new
                    Class[]{BuyHouse.class}, new DynamicProxyHandler(buyHouse));
            proxyBuyHouse.buyHosue();
        }
    }
    
    2.4. 动态代理实现(CGLIB代理)
    public class CglibProxy implements MethodInterceptor {
        private Object target;
        public Object getInstance(final Object target) {
            this.target = target;
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(this.target.getClass());
            enhancer.setCallback(this);
            return enhancer.create();
        }
    
        public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            System.out.println("买房前准备");
            Object result = methodProxy.invoke(object, args);
            System.out.println("买房后装修");
            return result;
        }
    }
    
    public class CglibProxyTest {
        public static void main(String[] args){
            BuyHouse buyHouse = new BuyHouseImpl();
            CglibProxy cglibProxy = new CglibProxy();
            BuyHouseImpl buyHouseCglibProxy = (BuyHouseImpl) cglibProxy.getInstance(buyHouse);
            buyHouseCglibProxy.buyHosue();
        }
    }
    

    总结:CGLIB创建的动态代理对象比JDK创建的动态代理对象的性能更高,但是CGLIB创建代理对象时所花费的时间却比JDK多得多。所以对于单例的对象,因为无需频繁创建对象,用CGLIB合适,反之使用JDK方式要更为合适一些。同时由于CGLib由于是采用动态创建子类的方法,对于final修饰的方法无法进行代理。

    相关文章

      网友评论

          本文标题:设计模式之观察和代理

          本文链接:https://www.haomeiwen.com/subject/xfjboftx.html