Java設計模式之從[Dota的武器創建]分析生成器(Builder)模式

  Dota可謂是當下最流行的遊戲之一,玩家分爲兩隊,分別是天輝(近衛)和夜魘(天災),每隊5個人,通過補刀、殺敵獲取經驗和金錢,金錢可用來購買強大的武器,最終推倒敵方基地則獲勝。我們現在考慮一個最簡單的武器組成元素:武器是由武器名、攻擊力、武器顏色組成,我們要想辦法實現能夠新建各種各樣武器的一個模式。假設我們預設了兩種武器,分別是聖劍(攻擊力300,黃色)、聖者遺物(攻擊力60,藍色),我將試着用生成器模式來做一個武器的生成小框架。

  生成器模式的意圖是將一個複雜對象與它的表示分離,使得同樣的構建過程可以創建不同的表示。

  我們將生成武器的抽象過程提取出來: 定義一個武器基類,包含武器名、攻擊力、顏色,以及打印武器信息的方法;然後我們通過爲武器命名並賦予攻擊力值、顏色來完成一個武器的生成,最後將生成的武器返回。Java代碼如下:

class Weapon{
    private String color;
    private String name;
    private int attack;
    public String getName(){
        return name;
    }
    public int getAttack(){
        return attack;
    }
    public String getColor(){
        return color;
    }
    public void setAttack(int _attack){ attack = _attack;}
    public void setName(String _name){ name = _name;}
    public void setColor(String _color){ color = _color;}

    public void print(){
        System.out.printf("武器名: %s, 攻擊力: %d, 顏色: %s\n", name, attack, color);
    }
}

interface WeaponBuilder {
    void buildBasicInformation();
    void buildColor();
    Weapon getWeapon();
}

class Weapons
{
    public static void build(WeaponBuilder builder){
        builder.buildBasicInformation();
        builder.buildColor();
    }
}

class DivineRapierBuilder implements WeaponBuilder{
    private Weapon weapon = new Weapon();
    public void buildBasicInformation(){
        weapon.setName("聖劍");
        weapon.setAttack(300);
    }
    public void buildColor(){
        weapon.setColor("黃色");
    }
    public Weapon getWeapon(){
        return weapon;
    }
}

class SacredRelicBuilder implements WeaponBuilder{
    private Weapon weapon = new Weapon();
    public void buildBasicInformation(){
        weapon.setName("聖者遺物");
        weapon.setAttack(60);
    }
    public void buildColor(){
        weapon.setColor("藍色");
    }
    public Weapon getWeapon(){
        return weapon;
    }
}

class Builder
{
    public static void main(String[] args) {
        WeaponBuilder divineRapierBuilder = new DivineRapierBuilder();
        Weapons.build(divineRapierBuilder);
        WeaponBuilder sacredRelicBuilder = new SacredRelicBuilder();
        Weapons.build(sacredRelicBuilder);
        Weapon divineRapier = divineRapierBuilder.getWeapon();
        Weapon sacredRelic = sacredRelicBuilder.getWeapon();
        divineRapier.print();
        sacredRelic.print();
    }
}

輸出結果爲:

武器名: 聖劍, 攻擊力: 300, 顏色: 黃色
武器名: 聖者遺物, 攻擊力: 60, 顏色: 藍色

  下面簡要來分析一下上面的代碼。Weapon類是記錄武器信息的一個類,我們最終就是要返回一個我們需要的Weapon對象。這個Weapon對象是一個比較複雜的對象,它由名稱和攻擊力兩個部分組成,我們把生成一個武器的必要方法聲明在WeaponBuilder接口中,接下來爲聖劍、聖者遺物兩個武器實現方法(分別是DivineRapierBuilder類和SacredRelicBuilder類)。最後,我們定義一個製造武器的類Weapons,裏面的靜態方法build傳入了一個WeaponBuilder對象,它會調用此對象的build,並返回getWeapon作爲結果。如main方法中所寫的那樣,我們總是可以調用Weapons.build來創建一個新的武器,Weapons本身並不創建武器,主要依靠的是傳入的WeaponBuilder來創建。如果我們需要建立一個新武器,我們只需要構造一個繼承了WeaponBuilder接口的類即可。

  在設計模式一書中談到,抽象工廠模式與Builder模式類似,都可以創建複雜對象;區別是Builder模式着重於一步步構造一個複雜對象,而抽象工廠着重於多個系列產品對象的創建(如上一篇博客的ProduceMarine、ProduceFirebat等),Builder在最後一步返回產品,而抽象工廠是立即返回的。

 

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章