代理模式

代理模式

1.定义

为其他对象提供一种代理以控制对这个对象的访问

2.普通代理

普通代理就是我们要知道代理对象的存在,他要求用户只能去访问代理对象,而不能访问真实对象

类图:

在这里插入图片描述

代码:

public interface IGamePlay {

    //登录游戏
    void login(String user,String password);

    //杀怪
    void killBoss();

    //升级
    void updateGrade();
}

被代理对象

public class GamePlay implements IGamePlay {

    private String name = "";

    //构造函数限制谁能创建对象,并同时传递姓名
    public GamePlay(IGamePlay iGamePlay , String name) throws Exception {
        if(iGamePlay == null){
            throw new Exception("iGamePlay is null");
        }else{
            this.name = name;
        }
    }

    @Override
    public void login(String user, String password) {
        System.out.println(this.name+"登录游戏");
    }

    @Override
    public void killBoss() {
        System.out.println(this.name+"在打怪");
    }

    @Override
    public void updateGrade() {
        System.out.println(this.name+"升级");
    }
}

代理对象

public class GamePlayProxy implements IGamePlay {

    private IGamePlay iGamePlay = null;

    public GamePlayProxy(String name){
        try {
            iGamePlay = new GamePlay(this,name);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void login(String user, String password) {
       this.iGamePlay.login("kevin","23");
    }

    @Override
    public void killBoss() {
        this.iGamePlay.killBoss();
    }

    @Override
    public void updateGrade() {
        this.iGamePlay.updateGrade();
    }
}

测试:

public class Test {

    public static void main(String[] args) {
        IGamePlay iGamePlay = new GamePlayProxy("kevin");
        iGamePlay.login("kevin","123");
        iGamePlay.killBoss();
        iGamePlay.updateGrade();
    }
}

在这里插入图片描述

在该模式下,调用者只知代理而不用知道真实的角色是谁,屏蔽了
真实角色的变更对高层模块的影响,真实的主题角色想怎么修改就怎么修改,对高层次的模
块没有任何的影响,只要你实现了接口所对应的方法,该模式非常适合对扩展性要求较高的 场合。

3.强制代理

强制代理却是要“强制”,你必须通过真实角色查找到代理角色,否则你不能访 问。甭管你是通过代理类还是通过直接new一个主题角色类,都不能访问,只有通过真实角 色指定的代理类才可以访问,也就是说由真实角色管理代理角色

在这里插入图片描述

public interface IGamePlay2 {
    //登录游戏
    void login(String user,String password);

    //杀怪
    void killBoss();

    //升级
    void updateGrade();

    //每个人都可以找一下自己的代理
    IGamePlay2 getProxy();
}

代理对象:

public class GamePlayProxy2 implements IGamePlay2 {

    private IGamePlay2 iGamePlay2 = null;

    public GamePlayProxy2(IGamePlay2 iGamePlay2){
        this.iGamePlay2 = iGamePlay2;
    }

    @Override
    public void login(String user, String password) {
        this.iGamePlay2.login(user, password);
    }

    @Override
    public void killBoss() {
        this.iGamePlay2.killBoss();
    }

    @Override
    public void updateGrade() {
        this.iGamePlay2.updateGrade();
    }

    @Override
    public IGamePlay2 getProxy() {
        return this;
    }
}

被代理对象

public class GamePlay2 implements IGamePlay2 {

    private String name = "";

    private GamePlayProxy2 proxy = null;

    public GamePlay2(String name) {
        this.name = name;
    }

    @Override
    public void login(String user, String password) {
        if(isProxy()) {
            System.out.println(this.name+"登录游戏");
        }else {
            System.out.println("无代理");
        }
    }

    @Override
    public void killBoss() {
        if(isProxy()) {
            System.out.println(this.name+"在打怪");
        }else {
            System.out.println("无代理");
        }
    }

    @Override
    public void updateGrade() {
        if(isProxy()) {
            System.out.println(this.name + "升级");
        }else {
            System.out.println("无代理");
        }
    }

    @Override
    public IGamePlay2 getProxy() {
        this.proxy = new GamePlayProxy2(this);
        return this.proxy;
    }

    //校验是否是代理访问
     private boolean isProxy(){
        if(this.proxy == null){
            return false;
        }else{
            return true;
        }
    }
}

测试:

public class Test {

    public static void main(String[] args) {
        GamePlay2 gamePlay2 = new GamePlay2("kevin");
        IGamePlay2 proxy = gamePlay2.getProxy();
        proxy.login("kevin","123");
        proxy.killBoss();
        proxy.updateGrade();
    }
}

在这里插入图片描述

强制代理的概念就是要从真实角色查找到代理角色,不允 许直接访问真实角色。高层模块只要调用getProxy就可以访问真实角色的所有方法,它根本
就不需要产生一个代理出来,代理的管理已经由真实角色自己完成。

4.动态代理

动态代理实现有两种方式,JDK 动态代理和 CGlib 动态代理,本文介绍JDK 动态代理

JDK 动态代理:创建动态代理类,实现 InvocationHandler 接口,重写 invoke 方法,在 invoke 方法中通过反射调用被代理类的方法,实现代理。jdk 动态代理只能代理接口,即只能代理接口的实现类

切面类

public class Aspect {

    public void before() {
        System.out.println("前方法");
    }

    public void after() {
        System.out.println("后方法");
    }
}

目标类

public interface Target {

    void targetMethod();
}

public class TargetClass implements Target {

    @Override
    public void targetMethod() {
        System.out.println("目标类实现目标方法");
    }
}

代理类

public class ProxyClass {

    public static Target createProxy(){
        final Target targetClass = new TargetClass();

        final Aspect aspect = new Aspect();

        Target proxy = (Target) Proxy.newProxyInstance(ProxyClass.class.getClassLoader(), targetClass.getClass().getInterfaces(), new InvocationHandler() {

            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
               aspect.before();

               Object result = method.invoke(targetClass,args);

               aspect.after();

               return result;
            }
        });
        return proxy;
    }
}

测试:

public class Test {

    public static void main(String[] args) {
        Target target = ProxyClass.createProxy();
        target.targetMethod();
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值