Java设计模式学习-代理模式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_40646143/article/details/85109086

代理模式核心作用:

  • 通过代理,控制对对象的防问 
  • 可以详细控制访问某个(某类)对象的方法 , 在调用这个方法前做前置处理 , 调用这个方法后做后置处理 。 (即 : AOP的微观实现)

代理模式(proxy pattern)

  • 核心角色 -- 定义代理角色和真实角色的公共对外方法 。
  • 真实角色 -- 实现抽象角色 , 定义真实角色所要实现的业务逻辑,供代理角色调用 。 -- 关注真正的业务逻辑
  • 代理角色 --  实现抽象角色,是真实角色的代理 ,通过真实角色的业务逻辑方法来实现抽象方法 ,并添加自己的操作。-将统一的流程放到代理橘色中处理

应用场景:

  • 安全代理 : 屏蔽对真实角色的直接访问 。
  • 远程代理 : 通过代理类处理远程方法调用(RMI) 。
  • 延迟代理 : 先加载轻量级的代理角色 ,真正需要时在加载真实对象 。

分类

  • 静态代理 -- 静态定义代理类
  • 动态代理 -- 动态生成代理类 
  • 1),JDK自带的动态代理
  • 2), javaassist字节码操作库实现 
  • 3), CCLIB 
  • 4),ASM(底层使用激光指令,可维护性比较差)

我们以用户租房子找中介来实现静态代理 入下

1),创建房东和中介公共接口类

/**房东/中介抽象接口类
 * @author 晓电脑
 */
public interface IntermediaryProxy {
    /**
     * 看房子
     */
    void houseInspection();


    /**
     * 签合同
     */
    void signAcontract();

    /**
     * 租房子
     */
    void RentAnApartment();


    /**
     * 付钱
     */
    void Pay();

}

2),创建真实角色 房东

/**房东 真实角色
 * @author 晓电脑
 */
public class RealRole implements IntermediaryProxy {
    @Override
    public void houseInspection() {
        System.out.println("看房子");
    }

    @Override
    public void signAcontract() {
        System.out.println("签合同");
    }

    @Override
    public void RentAnApartment() {
        System.out.println("三室一厅值得拥有,租下这个房子");
    }

    @Override
    public void Pay() {
        System.out.println("付钱");
    }
}

3),创建中介公司

/** 中介公司
 * @author 晓电脑
 */
public class IntermediaryAgent implements IntermediaryProxy {

    private  IntermediaryProxy intermediaryProxy;

    public IntermediaryAgent(IntermediaryProxy intermediaryProxy) {
        this.intermediaryProxy = intermediaryProxy;
    }

    @Override
    public void houseInspection() {
        System.out.println("带客户去看房子");
    }

    @Override
    public void signAcontract() {
        System.out.println("带客户签合同");
    }

    @Override
    public void RentAnApartment() {
        //真实房源
        intermediaryProxy.RentAnApartment();
    }

    @Override
    public void Pay() {
        System.out.println("付钱");
    }
}
  • 中介与房东 共同实现于 抽象的接口类
  • 中介类中含有真实角色的房源 如   intermediaryProxy.RentAnApartment();
     

4),创建客户来租房子 

/**
 * 相当于租房子的客户
 *
 * @author 晓电脑
 */
public class Client {
    public static void main(String[] args) {
        //创建真实角色
        IntermediaryProxy intermediaryProxy = new RealRole();
        //使用代理
        IntermediaryAgent agent = new IntermediaryAgent(intermediaryProxy);
        agent.houseInspection();
        agent.signAcontract();
        agent.RentAnApartment();
        agent.Pay();
    }
}

绘制uml图

                     

下面我们来看一下动态代理 

  • 动态代理相对于静态代理的优点
  • 抽象角色中(接口)声明的所以方法都被转移到调用处理器一个集中的方法中处理 , 这样,我们可以更加灵活和统一的处理众多的方法。

JDK自带动态代理

  • java.lang.reflect.Proxy  -- 作用: 动态生成代理类和对象 
  • java. lang. reflect . InvocationHandler(处理器接口) 
  • 1),可以通过invoke方法实现对真实角色的代理访问 
  • 2),每次通过Proxy 生成代理类对象对象时都要指定对象的处理器对象

1),创建明星抽象接口

public interface Star {
    /**
     * 签合同
     */
    void SignAcontract();

    /**
     * 唱歌
     */
    void sing();

    /**
     * 付钱
     */
    void pay();
}

2),创建真实明星 实现与抽象接口类

/**创建真实角色
 * @author 晓电脑
 */
public class RealStar implements Star {
    @Override
    public void SignAcontract() {
        System.out.println("签合同");
    }

    @Override
    public void sing() {
        System.out.println("周杰伦唱歌");
    }

    @Override
    public void pay() {
        System.out.println("付钱");
    }
}

3),创建动态代理类 需要实现与 InvocationHandler

/**使用JDK 自带的动态代理类
 * @author 晓电脑
 */
public class StarHandler implements InvocationHandler {

    private RealStar realStar;

    public StarHandler(RealStar realStar) {
        this.realStar = realStar;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //将核心方法进行隐藏 除了核心方法做了统一的流程处理
        System.out.println("真正方法执行前");
        System.out.println("签合同");
        if (method.getName().equals("sing")){
            method.invoke(realStar,args);
        }
        System.out.println("真正方法执行后");
        System.out.println("付钱");
        return null;
    }
}

4),创建测试的客户端类 Client类

/**
 * 测试动态代理客户端
 *
 * @author 晓电脑
 */
public class Cilent {
    public static void main(String[] args) {
        //创建真实角色
        RealStar star = new RealStar();
        //创建代理类实例
        StarHandler handler = new StarHandler(star);
        //生成代理对象
        Star star1 = (Star) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),
                new Class[]{Star.class},
                handler);

        star1.sing();
    }
}

运行如下

猜你喜欢

转载自blog.csdn.net/qq_40646143/article/details/85109086
今日推荐