代理模式

代理模式为另一个对象提供一个替身或占位符控制对这个对象的访问
假设现在你需要一笔贷款,那么你可以直接找银行,也可以找贷款经纪人,贷款经纪人能够提供更详细的信息、更便捷的服务。如果你的信用不够,或者想要更优惠的组合,银行可能不能让你满意。所以你需要一个贷款经纪人,一个代理(前面的都是扯蛋)。

java代码

// 银行接口
public interface Bank {

    int loan();
}

// 某家银行
public class WestBank implements Bank {
    @Override
    public int loan() {
        int count = new Random().nextInt(100);
        System.out.println("loan $" + count);
        return count;
    }
}

// 贷款经纪人
public class MortgageBroker implements Bank {

    private WestBank bank = new WestBank();

    @Override
    public int loan() {
        System.out.println("do something for you ... ");
        System.out.println("get more information");
        System.out.println("get more convenient service");
        System.out.println(" .... ");
        return bank.loan();
    }
}

// 测试类
public class Test {

    public static void main(String[] args) {
        new Test().test();
    }

    private void test() {
        // 原始途径
        Bank westBank = new WestBank();
        westBank.loan();
        // 通过贷款经纪人
        Bank mortgageBroker = new MortgageBroker();
        mortgageBroker.loan();
    }
}

注:

使用代理模式创建代表对象,让代表对象控制某对象的访问,被代理的对象可以是远程对象、创建开销大的对象或需要安全控制的对象
接下去可以了解一下动态代理。

虚拟代理

虚拟代理经常用于创建资源消耗较大的对象,在大对象创建完成前代替大对象处理任务,大对象创建完成后调用大对象方法。

java代码

// 大对象
public class LargeObject {

    // 模拟对象创建耗时
    public LargeObject() {
        try {
            int time = new Random().nextInt(2000) + 2000;
            System.out.println("please wait " + time);
            Thread.sleep(time);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void print() {
        System.out.println("largeObject do something");
    }
}

// 代理对象
public class LargeObjectProxy {

    private static volatile LargeObject largeObject;
    private static volatile boolean isFirst = true;

    // 代理方法
    public void print() {
        // 当第一次调用时,创建对象,并且代替原始对象做一些操作
        if (largeObject == null) {
            System.out.println("proxy do something");
            if (isFirst) {
                synchronized (LargeObjectProxy.class) {
                    if (largeObject == null && isFirst) {
                        isFirst = false;
                        Thread thread = new Thread(new LargeObjectThread());
                        thread.start();
                    }
                }
            }
        } else {
            // 对象创建成功后直接调用原始对象
            largeObject.print();
        }
    }

    private class LargeObjectThread implements Runnable {

        @Override
        public void run() {
            largeObject = new LargeObject();
            System.out.println("get object success ... ");
        }
    }
}

// 测试对象
public class Test {

    public static void main(String[] args) {
        new Test().test();
    }

    private void test() {
        LargeObjectProxy object = new LargeObjectProxy();

        // 模拟10次调用
        for (int i = 0; i < 10; i++) {
            object.print();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

注:

  1. 远程代理(Remote Proxy):为某个在不同的内存地址空间的对象提供局部代理,使系统可以将 Server 部分的实现隐藏,以便 Client 可以不必考虑 Server 的存在,类似于 C/S 模式(主要拦截并控制远程方法的调用,做代理防火墙之类的);
  2. 保护代理(Protection Proxy):是用代理控制对原始对象的访问,该类型的代理通常被用于原始对象有不同访问权限的情况;
  3. 智能引用(Smart Proxy):在访问原始对象时执行一些自己的附加操作并对指向原始对象的引用计数;
  4. 写时拷贝(克隆)代理(Copy-on-write Proxy):其实是虚拟代理的一个分支,提供了拷贝大对象的时候只有在对象真正变化后才会进行拷贝(克隆)的操作,即延迟拷贝。

代理模式需要为每个类都创建一个代理,比较繁琐。动态代理可以解决这个问题。

参考文章
1. Head First 设计模式
2. java/android 设计模式学习笔记(9):代理模式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值