Java设计模式之从[游戏场景读取]分析代理(Proxy)模式

  在大型游戏中(如刺客信条、使命召唤等),我们需要读取的地图往往是很大的。如果我们在进入游戏时,把所有的地图信息都读出来,会花费很多的时间。那么,为了提高效率,我们采取的措施是,我们并不需要真正把这些元素读取出来,可以先用一些“不怎么需要时间开销的替代品”(也就是我们谈到的代理)来代替这些需要花一定时间读取的实例,等到我们真正需要这些实例的时候,再将这些“替代品”换成实例即可。例如,在一个射击游戏中,前面有个房子,这个房子我们未必会进去。那么,在我们真正进入这个房子之前,这个房子内部是没有必要实例化的,我们只要通过它的外观判断出它是一个房子即可,房子内部的东西,等我们进去再生成来提升效率。

  代理的意图是为其他对象提供一种代理以控制这个对象的访问。在上面的比方中,我们要创建一个代理,来控制生成房子的方法(即:只有即将进入房间内部,才需要生成房间内部的对象)。下面,我稍微将这个例子简化了一下,请看Java代码:

interface House {
    void create() throws InterruptedException;
}

class LargeHouse implements House {
    public LargeHouse() throws InterruptedException{
        create();
    }
    public void create() throws InterruptedException{
        System.out.println("正在创建一个大房子……请等待2秒。");
        Thread.sleep(2000);
        System.out.println("房子创建完毕。");
    }
}

class LargeHouseProxy implements House {
    private LargeHouse largeHouse;
    public LargeHouseProxy(){   
    }
    public void create() throws InterruptedException{
        if (largeHouse == null) {
            largeHouse = new LargeHouse();
        }
    }
}

class Proxy
{
    public static void main(String[] args) throws InterruptedException {
        System.out.println("正在创建一个LargeHouse:");
        House largeHouse = new LargeHouse();
        System.out.println("正在创建一个LargeHouseProxy:");
        House largeHouseProxy = new LargeHouseProxy();
        System.out.println("LargeHouseProxy创建完毕!");
        largeHouseProxy.create();
    }
}

  我特意让程序等待2秒,来模拟创建房子的时间开销。下面简要来分析一下上面一段代码。

  假设我们已经事先有了House接口和LargeHouse类,LargeHouse类在创建的时候就会自动调用create方法来创建一个房子,这并不是我们想要的,因为它会一次性花费很多时间来初始化,我们是想要它在我们需要的时候才创建房子。那么,我马上建立了一个LargeHouseProxy类,它是LargeHouse的代理。我们可以从代码上看出,我们创建LargeHouseProxy的时候并没有马上创建LargeHouse,而是调用create()的时候,才创建了一个LargeHouse,通过这种方式来控制对对象的创建和初始化。这样做的好处之前也说过了,可以避免程序一次性将所有对象创建而造成巨大的开销,这种代理方式也叫做“虚代理”。

  程序的运行结果如下:

正在创建一个LargeHouse:

正在创建一个大房子……请等待2秒。

房子创建完毕。

正在创建一个LargeHouseProxy:

LargeHouseProxy创建完毕!

正在创建一个大房子……请等待2秒。

房子创建完毕。

  代理的应用之一是智能指针。如在C/C++语言中,没有垃圾回收机制,我们可以为指针添加一个代理,让它进行指针的计数,通过数量的统计来实现代理所管理的指针指向的内存能够自动释放来避免内存泄露等。

  乍一看代理模式和装饰模式似乎挺像,因为它们均是为一个类中的方法来添加一些额外的行为,然而装饰模式可以动态继承来为方法提供额外行为,是为了递归组合而设计的(请见Java设计模式之再从[暗黑破坏神"装备镶嵌宝石系统"]分析装饰(Decorator)模式),而代理模式的目的是,当直接访问一个实体不方便或不符合需求时,为这个实体提供一个替代品。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值