Java教程

Java 23种设计模式系列之代理模式(常用)

本文主要是介绍Java 23种设计模式系列之代理模式(常用),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

目录

一、代理模式

二、静态代理

三、动态代理(为了解决静态代理的缺点)


一、代理模式

1.什么是代理模式?

代理模式就是给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。

通俗的来讲代理模式就是我们生活中常见的中介。

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

特征:代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。

代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。

代理模式(Proxy)结构图

 Subject类,定义了RealSubject和Proxy的共用接口,这样就可在任何使用RealSubject的地方可以使用Proxy。(可称为抽象角色)

RealSubject类,定义了Proxy所代表的真是实体(也就是上述所说的委托类,称为真是角色)

Proxy类,保存了一个引用使得代理可以访问实体,并提供了一个与Subjet的接口相同的接口,这样代理就可以用来替代实体。(中介,称为代理角色)

 

2.为什么要用代理模式?

1)开闭原则,增加功能(代理模式在不修改原有代码的基础上,通过代理类扩展委托类的功能。)

比如:我们想给项目加入缓存、日志这些功能,我们就可以使用代理类来完成,而没必要打开已经封装好的委托类。

2)中介隔离作用

(在某些情况下,一个客户类不想或者不能直接引用一个委托对象,而代理类对象可以在客户类和委托对象之间起到中介的作用,其特征是代理类和委托类实现相同的接口。)

3.有哪几种代理模式?

1)静态代理

由程序员创建或特定工具自动生成源代码,在对其编译。在程序运行之前,代理类.class文件就已经被创建了

2)动态代理

能够在程序运行时JVM才为被代理对象生成代理对象。

二、静态代理

简单代码实现:

    // 接口
    interface IStar {
        void sing();
    }

    // 真实对象
    class LDHStar implements IStar {
        @Override
        public void sing() {
            System.out.println("刘德华唱歌");
        }

    }

    // 代理类需要有真实对象的控制权 (引用)
    class ProxyManger implements IStar {
        
        // 真实对象的引用
        private IStar star;
        
        public ProxyManger() {
            super();
        }

        public ProxyManger(IStar star) {
            super();
            this.star = star;
        }
        
        @Override
        public void sing() {
      System.out.println("唱歌前准备");
        star.sing();
       System.out.println("善后工作");        }
    }
class Test{
public static void main(String[] args) {
            // 创建明星对象
            IStar ldh = new LDHStar();
            ProxyManger proxy = new ProxyManger(ldh);
            proxy.sing();
        }
}

结果:

 

静态代理总结:
优点:可以做到在不修改目标对象的功能前提下,对目标功能扩展.
缺点:因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类,类太多.同时,一旦接口增          加方法,目标对象与代理对象都要维护.

三、动态代理(为了解决静态代理的缺点)

1.动态代理和静态代理角色一样
2.动态代理的代理类是动态生成的,不是我们直接写好的
3.动态代理分为两大类:基于接口的动态代理,基于类的动态代理
         基于接口----JDK动态代理
         基于类----cglib
         java字节码实现---javasist

需要了解的两个类:

invocationHandle类:调用处理程序,返回结果

proxy类:提供创建动态代理类和实例的静态方法

//目标类接口interface IDog{
    void run();
}
//目标类
class GunDog implements IDog{

    @Override
    public void run() {
        System.out.println("猎狗在跑");
    }
}
class DogUtils{
    public static void method1() {
        System.out.println("增强方式一");
    }
    
    public static void method2() {
        System.out.println("增强方式二");
    }
}
class MyInvocationHandle implements InvocationHandler{
    private Object target;
    public void setTarget(Object target) {
        this.target = target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            DogUtils.method1();
            method.invoke(target, args);
            DogUtils.method2();
            return null;
    }
}
    //生产代理对象的工厂
 class MyProxyFactory{
    public static Object getProxy(Object target) {
        MyInvocationHandle handle = new MyInvocationHandle();
        handle.setTarget(target);
        Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handle);
        return proxy;
    }
 }
public class ProxyDemo {
    public static void main(String[] args) {
      IDog dog = new GunDog();
      IDog proxy =(IDog) MyProxyFactory.getProxy(dog);
      proxy.run();
    }

}

结果:

 总结:代理对象不需要实现接口,但是目标对象一定要实现接口,否则不能使用动态代理,因此这也算是这种方式的缺陷。

这篇关于Java 23种设计模式系列之代理模式(常用)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!