抽象工廠模式 Abstract Factory Pattern 2

現在已經有各式各樣的工廠可以生產裝備,接下來就看看實際上要怎麼給冒險者裝備。
首先要先為冒險者增加兩個屬性,武器Weapon,衣服Clothes。
接下來訓練營內必須要有對應的工廠來生產對應的裝備。
最後呼叫的客戶端程式與工廠模式 Factory一樣,不過現在冒險者們在訓練後就會獲得基礎裝備了。

測試碼:

跟抽象工廠模式沒關係的冒險者,這些只是為了測試用

//工廠與各種裝備同上頁

/**
 * 冒險者
 */
public abstract class Adventurer {
    protected Weapon weapon;    //武器
    protected Clothes clothes;  //衣服
    /**
     * 看冒險者的狀態
     */
    public abstract void display();
    // getter & setter 省略
}

/**
 * 實體工廠-弓箭手訓練營
 */
public class ArcherTrainingCamp implements TrainingCamp {
    private static EquipFactory factory = new ArcherEquipFactory();

    @Override
    public Adventurer trainAdventurer() {
        System.out.println("訓練一個弓箭手");
        Archer archer = new Archer();
        // ...進行基本訓練
        // ...弓箭手訓練課程
        // 訓練完成配發裝備
        archer.setWeapon(factory.productWeapon());
        archer.setClothes(factory.productArmor());
        return archer; 
    }

}

/**
 *  工廠介面-冒險者訓練營(這只是一個概念或規範,要訓練什麼,怎麼訓練留給子類別實作)
 */
public interface TrainingCamp {
    /**
     * 訓練冒險者的過程,訓練後請給我一個冒險者
     */
    public Adventurer trainAdventurer();

}



/**
 * 實體工廠-弓箭手訓練營
 */
public class ArcherTrainingCamp implements TrainingCamp {
    private static EquipFactory factory = new ArcherEquipFactory();

    @Override
    public Adventurer trainAdventurer() {
        System.out.println("訓練一個弓箭手");
        Archer archer = new Archer();
        // ...進行基本訓練
        // ...弓箭手訓練課程
        // 訓練完成配發裝備
        archer.setWeapon(factory.productWeapon());
        archer.setClothes(factory.productArmor());
        return archer; 
    }
}

/**
 * 實體工廠-鬥士訓練營
 */
public class WarriorTrainingCamp implements TrainingCamp {
    private static EquipFactory factory = new WarriorEquipFactory();

    @Override
    public Adventurer trainAdventurer() {
        System.out.println("訓練一個鬥士");
        Warrior warrior = new Warrior();
        // ...進行基本訓練
        // ...鬥士訓練課程

        // 訓練完成配發裝備
        warrior.setWeapon(factory.productWeapon());
        warrior.setClothes(factory.productArmor());
        return warrior; 
    }
}

/**
 * 弓箭手
 */
public class Archer extends Adventurer {

    @Override
    public void display() {
        System.out.println("我是弓箭手,裝備:");
        weapon.display();
        System.out.println();
        clothes.display();
        System.out.println();
    }
}

/**
 * 鬥士
 */
public class Warrior extends Adventurer {
    @Override public void display() {
        System.out.println("我是弓箭手,裝備:");
        weapon.display();
        System.out.println();
        clothes.display();
        System.out.println();
    }
}

測試碼:

/**
 * 抽像工廠模式-測試
 */
public class EquipFactoryTest {
    private EquipFactory equipFactory;
    @Test
    /**
     * 測試工廠是否能正確生產裝備
     */
    public void equipFactoryTest(){
        System.out.println("==========抽像工廠模式測試==========");

        // 幫弓箭手生產裝備
        equipFactory = new ArcherEquipFactory();
        Clothes archerLeather = equipFactory.productArmor();
        Weapon archerBow = equipFactory.productWeapon();

        // 皮甲的防禦應該是5,弓的攻擊為10,範圍為10
        Assert.assertEquals(5, archerLeather.getDef());
        Assert.assertEquals(10, archerBow.getAtk());
        Assert.assertEquals(10, archerBow.getRange());


        // 幫鬥士生產裝備
        equipFactory = new WarriorEquipFactory();
        Clothes armor = equipFactory.productArmor();
        Weapon longSword = equipFactory.productWeapon();

        // 盔甲的防禦應該是10,弓的攻擊為10,範圍為1
        Assert.assertEquals(10, armor.getDef());
        Assert.assertEquals(10, longSword.getAtk());
        Assert.assertEquals(1, longSword.getRange());


        // 弓箭手訓練營
        TrainingCamp camp = new ArcherTrainingCamp();
        // 訓練弓箭手
        Adventurer archer = camp.trainAdventurer();

        // 鬥士訓練營
        camp = new WarriorTrainingCamp();
        // 訓練鬥士
        Adventurer warrior = camp.trainAdventurer();

        archer.display();
        warrior.display();
    }
}

測試結果:

==========抽像工廠模式測試==========
我是弓箭手,裝備:
  Bow atk:10 range:10
  Leather def:5
我是弓箭手,裝備:
  LongSword atk:10 range:1
  Armor def:10

results matching ""

    No results matching ""