Java设计模式之从[魔兽世界副本]分析原型(Prototype)模式

  “副本”是网络游戏任务的一种形式,它最初出现于无尽的任务,现在运用得最有名的就是魔兽世界的副本了,我们将它称为副本任务。副本任务一般是一个队伍的人一起闯关的,假设有队伍A、队伍B、队伍C,分别对同一个副本任务发出挑战,他们在副本任务中的行为是不相干的。也就是说,A队伍在副本任务中消灭boss、开启宝箱,不会对B、C两支队伍造成任何影响,B、C同理。因此,“副本”可以理解成,从任务的原型中拷贝,然后给不同的队伍去执行。

  现在从“原型模式”来思考一下副本的实现(真正的魔兽世界是如何实现的我不知道)。原型模式的意图是从原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。以魔兽世界中的“死亡矿井”副本为例,它是一个最基本的副本,玩家达到10级就可以接受此副本任务。为了简化模型,我把副本任务的属性分为任务名、敌人数量和难度等级。若玩家进入了一个副本任务,游戏则先会寻找这个副本任务的原型(也就是一个对象),接下来把这个对象复制(clone)一次,再把复制好的对象返回给玩家,告诉玩家:你的副本任务我已经复制好了,由于是从原型中拷贝下来的,所以你在这个任务里怎么样都不会影响到别人。

  以下是Java代码:

interface Cloneable{
    Object clone();
}

class Deadmines implements Cloneable {
    String mapName = "死亡矿井";
    int enemies ;
    int difficulty ;
    public Deadmines(int _difficulty, int _enemies){
        difficulty = _difficulty;
        enemies = _enemies;
    }
    public Object clone(){
        return new Deadmines(difficulty, enemies);
    }
    public void print(){
        System.out.printf("副本名: %s, 敌人数目: %d, 难度: %d\n", mapName, enemies, difficulty); 
    }
}

class Prototype
{
    public static void main(String[] args) {
        Deadmines deadminesPrototype = new Deadmines(10, 200);
        Deadmines playerDeadmines = (Deadmines)deadminesPrototype.clone();
        playerDeadmines.print();
        System.out.println(deadminesPrototype == playerDeadmines);
    }
}

输出结果:

副本名: 死亡矿井, 敌人数目: 200, 难度: 15
false

  稍微说明一下。main方法中的最后一行是用于判断原型和副本是否为同一引用,结果显然是false,因为副本是被拷贝出来的,并不是直接返回原型。通俗地来讲,原型模式就是以一个对象为模板,来构造与它一样的对象。它可以隐藏具体的克隆细节(如我们在使用时只需要调用clone方法,而不需要知道它是怎么clone的)。

  另外还要提到的是,在Java中本身就存在Cloneable接口,在上例中我们是自己重新定义了一个Cloneable。另外,Object类中本身也有一个受保护的方法clone,它可用于改写。在Java文档中写道,Object的clone方法没有继承Cloneable接口,如果直接调用,则会触发CloneNotSupportedException异常。能够调用clone方法的对象一定要继承Cloneable接口。(CloneNotSupportedException - if the object's class does not support the Cloneable interface. Subclasses that override the clone method can also throw this exception to indicate that an instance cannot be cloned.)

  总结一下,当一个系统应该独立于它产品创建、构成时、实例化的对象是运行时加载(如副本任务)时、为了避免创建一个与产品类层次平行的工厂类层次时、当一个类的实例只能有几个不同状态组合中的一种时,可以考虑使用原型模式。它在Java、C#中得到了广泛的应用。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值