Java设计模式之从[暗黑破坏神"装备镶嵌宝石系统"]分析桥接(Bridge)模式

  暴雪公司著名的游戏暗黑破坏神中,有一个经典的"镶嵌系统",例如,可以为武器镶嵌红宝石、蓝宝石来得到攻击特效或攻击力加成,为防具镶嵌红宝石、蓝宝石来得到攻击特效或者防御力的加成。不同的宝石加在不同的装备上会有不同效果,如宝石加在武器上则提升武器攻击力,加在防具上则提升防御力。

  假设我们建立了一个剑类(Sword)和一个盾类(Shield),建立了一个红宝石类(Ruby)和一个蓝宝石类(Sapphire)。由于装备可以镶嵌宝石,那么这两个部分是可以两两组合的,为此,我们必须要写出4个类来表示它们的全部组合: SwordWithRuby, SwordWithSapphire, ShieldWithRuby, ShieldWithSapphire,代码编写十分繁琐。产生这种情况的原因是,“装备镶嵌宝石”存在这两个维度的变化(武器种类,宝石种类),假设有n种武器,m种宝石,为了实现这个机制,我们不得不构造m * n个类。

  这个时候,我们可以用桥接模式来进行设计。

  桥接模式的意图是将抽象部分与它的实现部分分离,使它们可以独立变化。在镶嵌系统中,抽象部分是什么?抽象部分就是武器镶嵌宝石的一个抽象类(EquipmentRubyBridge);实现部分是什么?实现部分是每种宝石的效果(Jewel)。代码如下:

interface Jewel {
    String name() ;
}

class Ruby implements Jewel {
    public String name (){
        return "红宝石";
    }
}

class Sapphire implements Jewel {
    public String name (){
        return "蓝宝石";
    }
}

class Sword extends EquipmentRubyBridge{
    public Sword(Jewel j) {
        super(j);
    }
    public void print(){
        System.out.println("为剑嵌入了一颗" + getJewel().name() );
    }
}

class Shield extends EquipmentRubyBridge{
    public Shield(Jewel j) {
        super(j);
    }
    public void print(){
        System.out.println("为盾嵌入了一颗" + getJewel().name() );
    }
}

abstract class EquipmentRubyBridge{
    private Jewel jewel;
    protected Jewel getJewel () { return jewel;}
    public EquipmentRubyBridge(Jewel j){
        jewel = j;
    }
    public abstract void print();
}


class Bridge {
    public static void main(String[] args) {
        Jewel sapphire = new Sapphire();
        Jewel ruby = new Ruby();
        EquipmentRubyBridge sword = new Sword(ruby);
        EquipmentRubyBridge shield = new Shield(sapphire);
        sword.print();
        shield.print();
    }
}
运行结果:

为剑嵌入了一颗红宝石
为盾嵌入了一颗蓝宝石

  简要分析一下上面的代码。EquipmentRubyBridge是镶嵌机制的抽象,它规定了它的子类中包含了Jewel接口,Jewel接口为宝石的实现接口。对于EquipmentRubyBridge的子类,它必然组合了一个Jewel对象,也就是说,EquipmentRubyBridge如同一个桥梁,将它的子类和实现部分(Jewel)组合在了一起。如Shield类,继承于EquipmentRubyBridge,在print方法中,调用了Jewel的getJewel().name()方法 —— EquipmentRubyBridge子类可以自己扩充print方法,也可以传入各种Jewel类,这样就实现了抽象部分和实现部分的独立。

  在《设计模式》中说,当不希望在抽象和它的实现之间有一个固定的绑定模式时(本例中,武器并没有和特定宝石做绑定)时可以用桥接。类的抽象以及它的实现都应该可以通过生成子类的方法进行扩充。如我们可以继承EquipmentRubyBridge建立一个新的武器,或者继承Jewel来建立一个新的宝石。

你可能感兴趣的:(从实例角度分析Java设计模式)