將行為拆成請求與執行兩個區塊,請求的部分獨自封裝成物件,執行的部分則交由專門負責執行的物件。
負責執行的物件除了儲存等待執行的請求,還可以在執行前取消特定請求。
想像一個情況,使用者可以很簡單地說出要執行的行為,負責執行的程式可以迅速反應,轉換到設計上,單個要執行的行為,經常包裝成物件,物件內有執行的細節。
現在情況改變,有許多的行為可以執行,那要建立相同數量的物件,數量越多,越不容易管理,因為分散各地。
此外,如果需要一個歷史清單追蹤要執行的行為,以及取消特定行為呢?
單純的「傳球、接球」模式無法做到。
為了實踐這兩個新需求,可以將執行的細節封裝在特定物件內,原本的包裝行為的物件簡化成呼叫特定物件內的對應方法。
實踐的作法是:
以下範例以「模擬世紀帝國二的基本操作」為核心製作。
單位物件:Villager
、Paladin
、House
、Castle
public class Villager {
private int healthPoints;
private Headquarters headquarters;
public Villager(Headquarters headquarters) {
healthPoints = 25;
this.headquarters = headquarters;
}
public void gotDamage(int damagePoints) {
healthPoints -= damagePoints;
if (healthPoints < 0) {
headquarters.removeVillager();
}
}
}
public class Paladin {
private int healthPoints;
private Headquarters headquarters;
public Paladin(Headquarters headquarters) {
healthPoints = 160;
this.headquarters = headquarters;
}
public void gotDamage(int damagePoints) {
healthPoints -= damagePoints;
if (healthPoints < 0) {
headquarters.removePaladin();
}
}
}
public class House {
private int healthPoints;
private Headquarters headquarters;
public House(Headquarters headquarters) {
healthPoints = 550;
this.headquarters = headquarters;
}
public void gotDamage(int damagePoints) {
healthPoints -= damagePoints;
if (healthPoints < 0) {
headquarters.removeHouse();
}
}
}
public class Castle {
private int healthPoints;
private Headquarters headquarters;
public Castle(Headquarters headquarters) {
healthPoints = 4800;
this.headquarters = headquarters;
}
public void gotDamage(int damagePoints) {
healthPoints -= damagePoints;
if (healthPoints < 0) {
headquarters.removeCastle();
}
}
}
特定物件(Receiver)
public class Headquarters {
private int woodCounts;
private int foodCounts;
private int goldCounts;
private int stoneCounts;
private ArrayList<Villager> villagerList = new ArrayList<>();
private ArrayList<Paladin> paladinList = new ArrayList<>();
private ArrayList<House> houseList = new ArrayList<>();
private ArrayList<Castle> castleList = new ArrayList<>();
public Headquarters() {
woodCounts = 100;
foodCounts = 100;
goldCounts = 50;
stoneCounts = 50;
}
public void createVillager() {
if (foodCounts < 50) {
System.out.println("食物不足,無法生產村民\n");
} else {
System.out.println("食物充足,已生產村民\n");
villagerList.add(new Villager(this));
foodCounts -= 50;
}
}
public void removeVillager() {
if (villagerList.isEmpty()) {
System.out.println("沒有村民可以刪除");
} else {
villagerList.remove(0);
System.out.println("村民已刪除");
}
}
public void createPaladin() {
if (foodCounts < 60) {
System.out.println("食物不足,無法生產遊俠\n");
} else if (goldCounts < 75) {
System.out.println("黃金不足,無法生產遊俠\n");
} else {
System.out.println("食物充足,已生產遊俠\n");
paladinList.add(new Paladin(this));
foodCounts -= 60;
goldCounts -= 75;
}
}
public void removePaladin() {
if (paladinList.isEmpty()) {
System.out.println("沒有遊俠可以刪除");
} else {
paladinList.remove(0);
System.out.println("遊俠已刪除");
}
}
public void createHouse() {
if (woodCounts < 25) {
System.out.println("木頭不足,無法建造居住房舍\n");
} else {
System.out.println("木頭充足,已建造居住房舍\n");
houseList.add(new House(this));
woodCounts -= 25;
}
}
public void removeHouse() {
if (houseList.isEmpty()) {
System.out.println("沒有居住房舍可以刪除");
} else {
houseList.remove(0);
System.out.println("居住房舍已刪除");
}
}
public void createCastle() {
if (stoneCounts < 650) {
System.out.println("石頭不足,無法建造城堡\n");
} else {
System.out.println("石頭充足,已建造城堡\n");
castleList.add(new Castle(this));
stoneCounts -= 600;
}
}
public void removeCastle() {
if (castleList.isEmpty()) {
System.out.println("沒有城堡可以刪除");
} else {
castleList.remove(0);
System.out.println("城堡已刪除");
}
}
public void gatherWood() {
if (villagerList.isEmpty()) {
System.out.println("沒有村民可用\n");
} else {
System.out.println("村民數量足夠,開始砍樹\n");
woodCounts += 100;
}
}
public void gatherFood() {
if (villagerList.isEmpty()) {
System.out.println("沒有村民可用\n");
} else {
System.out.println("村民數量足夠,開始採集食物\n");
foodCounts += 100;
}
}
public void gatherGold() {
if (villagerList.isEmpty()) {
System.out.println("沒有村民可用\n");
} else {
System.out.println("村民數量足夠,開始挖金礦\n");
goldCounts += 100;
}
}
public void gatherStone() {
if (villagerList.isEmpty()) {
System.out.println("沒有村民可用\n");
} else {
System.out.println("村民數量足夠,開始挖石礦\n");
stoneCounts += 100;
}
}
public void showResources() {
System.out.println("---當前資源---");
System.out.println("木頭: " + woodCounts);
System.out.println("食物: " + foodCounts);
System.out.println("黃金: " + goldCounts);
System.out.println("石頭: " + stoneCounts);
System.out.println("---當前建築數量---");
System.out.println("居住房舍: " + houseList.size());
System.out.println("城堡: " + castleList.size());
System.out.println("---當前單位數量---");
System.out.println("村民: " + villagerList.size());
System.out.println("遊俠: " + paladinList.size());
System.out.println("---完畢---\n");
}
}
行為的虛擬層親代:Command
public abstract class Command {
protected Headquarters headquarters;
protected Command(Headquarters headquarters) {
this.headquarters = headquarters;
}
public abstract void executeCommand();
public abstract String getName();
}
行為子代:CreateVillagerCommand
、RemoveVillagerCommand
、CreatePaladinCommand
、RemovePaladinCommand
、CreateHouseCommand
、RemoveHouseCommand
、CreateCastleCommand
、RemoveCastleCommand
、GatherFoodCommand
、GatherGoldCommand
、GatherStoneCommand
、GatherWoodCommand
、ShowResourcesCommand
(Command 物件)
public class CreateVillagerCommand extends Command {
private String name = "生產村民";
public CreateVillagerCommand(Headquarters headquarters) {
super(headquarters);
}
@Override
public void executeCommand() {
headquarters.createVillager();
}
@Override
public String getName() {
return name;
}
}
public class RemoveVillagerCommand extends Command {
private String name = "刪除村民";
public RemoveVillagerCommand(Headquarters headquarters) {
super(headquarters);
}
@Override
public void executeCommand() {
headquarters.removeVillager();
}
@Override
public String getName() {
return name;
}
}
public class CreatePaladinCommand extends Command {
private String name = "生產遊俠";
public CreatePaladinCommand(Headquarters headquarters) {
super(headquarters);
}
@Override
public void executeCommand() {
headquarters.createPaladin();
}
@Override
public String getName() {
return name;
}
}
public class RemovePaladinCommand extends Command {
private String name = "刪除遊俠";
public RemovePaladinCommand(Headquarters headquarters) {
super(headquarters);
}
@Override
public void executeCommand() {
headquarters.removePaladin();
}
@Override
public String getName() {
return name;
}
}
public class CreateHouseCommand extends Command {
private String name = "建造居住房舍";
public CreateHouseCommand(Headquarters headquarters) {
super(headquarters);
}
@Override
public void executeCommand() {
headquarters.createHouse();
}
@Override
public String getName() {
return name;
}
}
public class RemoveHouseCommand extends Command {
private String name = "刪除居住房舍";
public RemoveHouseCommand(Headquarters headquarters) {
super(headquarters);
}
@Override
public void executeCommand() {
headquarters.removeHouse();
}
@Override
public String getName() {
return name;
}
}
public class CreateCastleCommand extends Command {
private String name = "建造城堡";
public CreateCastleCommand(Headquarters headquarters) {
super(headquarters);
}
@Override
public void executeCommand() {
headquarters.createCastle();
}
@Override
public String getName() {
return name;
}
}
public class RemoveCastleCommand extends Command {
private String name = "刪除城堡";
public RemoveCastleCommand(Headquarters headquarters) {
super(headquarters);
}
@Override
public void executeCommand() {
headquarters.removeCastle();
}
@Override
public String getName() {
return name;
}
}
public class GatherFoodCommand extends Command {
private String name = "採集食物";
public GatherFoodCommand(Headquarters headquarters) {
super(headquarters);
}
@Override
public void executeCommand() {
headquarters.gatherFood();
}
@Override
public String getName() {
return name;
}
}
public class GatherGoldCommand extends Command {
private String name = "挖金礦";
public GatherGoldCommand(Headquarters headquarters) {
super(headquarters);
}
@Override
public void executeCommand() {
headquarters.gatherGold();
}
@Override
public String getName() {
return name;
}
}
public class GatherStoneCommand extends Command {
private String name = "挖石礦";
public GatherStoneCommand(Headquarters headquarters) {
super(headquarters);
}
@Override
public void executeCommand() {
headquarters.gatherStone();
}
@Override
public String getName() {
return name;
}
}
public class GatherWoodCommand extends Command {
private String name = "砍樹";
public GatherWoodCommand(Headquarters headquarters) {
super(headquarters);
}
@Override
public void executeCommand() {
headquarters.gatherWood();
}
@Override
public String getName() {
return name;
}
}
public class ShowResourcesCommand extends Command {
private String name = "顯示資源、建築與單位";
public ShowResourcesCommand(Headquarters headquarters) {
super(headquarters);
}
@Override
public void executeCommand() {
headquarters.showResources();
}
@Override
public String getName() {
return name;
}
}
對外窗口(Invoker):GUI
public class GUI {
private ArrayList<Command> orders;
public GUI() {
this.orders = new ArrayList<>();
}
public void receivePlayerCommand(Command command) {
orders.add(command);
System.out.println("接收指令: " + command.getName() + " 時間:" + new Date());
}
public void cancelPlayerCommand(Command command) {
orders.remove(command);
System.out.println("取消指令: " + command.getName() + " 時間:" + new Date());
}
public void executePlayerCommands() {
for (Command command : orders) {
command.executeCommand();
}
}
}
測試,玩家嘗試建造房屋、城堡,生產村民、遊俠,採集木頭、食物、黃金、石頭,最後顯示資源與單位數量:RTSCommandSample
public class RTSCommandSample {
public static void main(String[] args) {
Headquarters headquarters = new Headquarters();
Command createVillagerCommand = new CreateVillagerCommand(headquarters);
Command createPaladinCommand = new CreatePaladinCommand(headquarters);
Command createHouseCommand = new CreateHouseCommand(headquarters);
Command createCastleCommand = new CreateCastleCommand(headquarters);
Command gatherWoodCommand = new GatherWoodCommand(headquarters);
Command gatherFoodCommand = new GatherFoodCommand(headquarters);
Command gatherGoldCommand = new GatherGoldCommand(headquarters);
Command gatherStoneCommand = new GatherStoneCommand(headquarters);
Command showResourcesCommand = new ShowResourcesCommand(headquarters);
GUI gui = new GUI();
gui.receivePlayerCommand(createVillagerCommand);
gui.receivePlayerCommand(createPaladinCommand);
gui.receivePlayerCommand(gatherFoodCommand);
gui.receivePlayerCommand(gatherFoodCommand);
gui.receivePlayerCommand(gatherGoldCommand);
gui.receivePlayerCommand(gatherGoldCommand);
gui.receivePlayerCommand(createPaladinCommand);
gui.receivePlayerCommand(createHouseCommand);
gui.receivePlayerCommand(createHouseCommand);
gui.receivePlayerCommand(createHouseCommand);
gui.receivePlayerCommand(createHouseCommand);
gui.receivePlayerCommand(createHouseCommand);
gui.receivePlayerCommand(gatherWoodCommand);
gui.receivePlayerCommand(createHouseCommand);
gui.cancelPlayerCommand(createHouseCommand);
gui.cancelPlayerCommand(createHouseCommand);
gui.receivePlayerCommand(createCastleCommand);
gui.receivePlayerCommand(gatherStoneCommand);
gui.receivePlayerCommand(gatherStoneCommand);
gui.receivePlayerCommand(gatherStoneCommand);
gui.receivePlayerCommand(gatherStoneCommand);
gui.receivePlayerCommand(gatherStoneCommand);
gui.receivePlayerCommand(gatherStoneCommand);
gui.receivePlayerCommand(gatherStoneCommand);
gui.receivePlayerCommand(gatherStoneCommand);
gui.cancelPlayerCommand(gatherStoneCommand);
gui.receivePlayerCommand(createCastleCommand);
gui.receivePlayerCommand(showResourcesCommand);
gui.executePlayerCommands();
}
}
單位物件:Villager
、Paladin
、House
、Castle
class Villager {
/** @param {Headquarters} headquarters */
constructor(headquarters) {
this.healthPoints = 25;
this.headquarters = headquarters;
}
/** @param {number} damagePoints */
/** @param {number} damagePoints */
gotDamage(damagePoints) {
this.healthPoints -= damagePoints;
if (this.healthPoints < 0) {
this.headquarters.removeVillager();
}
}
}
class Paladin {
/** @param {Headquarters} headquarters */
constructor(headquarters) {
this.healthPoints = 160;
this.headquarters = headquarters;
}
/** @param {number} damagePoints */
gotDamage(damagePoints) {
this.healthPoints -= damagePoints;
if (this.healthPoints < 0) {
this.headquarters.removePaladin();
}
}
}
class House {
/** @param {Headquarters} headquarters */
constructor(headquarters) {
this.healthPoints = 550;
this.headquarters = headquarters;
}
/** @param {number} damagePoints */
gotDamage(damagePoints) {
this.healthPoints -= damagePoints;
if (this.healthPoints < 0) {
this.headquarters.removeHouse();
}
}
}
class Castle {
/** @param {Headquarters} headquarters */
constructor(headquarters) {
this.healthPoints = 4800;
this.headquarters = headquarters;
}
/** @param {number} damagePoints */
gotDamage(damagePoints) {
this.healthPoints -= damagePoints;
if (this.healthPoints < 0) {
this.headquarters.removeCastle();
}
}
}
特定物件(Receiver)
class Headquarters {
constructor() {
this.woodCounts = 100;
this.foodCounts = 100;
this.goldCounts = 50;
this.stoneCounts = 50;
/** @type {Villager[]} */
this.villagerList = [];
/** @type {Paladin[]} */
this.paladinList = [];
/** @type {House[]} */
this.houseList = [];
/** @type {Castle[]} */
this.castleList = [];
}
createVillager() {
if (this.foodCounts < 50) {
console.log("食物不足,無法生產村民\n");
} else {
console.log("食物充足,已生產村民\n");
this.villagerList.push(new Villager(this));
this.foodCounts -= 50;
}
}
removeVillager() {
if (this.villagerList.length === 0) {
console.log("沒有村民可以刪除");
} else {
this.villagerList.shift();
console.log("村民已刪除");
}
}
createPaladin() {
if (this.foodCounts < 60) {
console.log("食物不足,無法生產遊俠\n");
} else if (this.goldCounts < 75) {
console.log("黃金不足,無法生產遊俠\n");
} else {
console.log("食物充足,已生產遊俠\n");
this.paladinList.push(new Paladin(this));
this.foodCounts -= 60;
this.goldCounts -= 75;
}
}
removePaladin() {
if (this.paladinList.length === 0) {
console.log("沒有遊俠可以刪除");
} else {
this.paladinList.shift();
console.log("遊俠已刪除");
}
}
createHouse() {
if (this.woodCounts < 25) {
console.log("木頭不足,無法建造居住房舍\n");
} else {
console.log("木頭充足,已建造居住房舍\n");
this.houseList.push(new House(this));
this.woodCounts -= 25;
}
}
removeHouse() {
if (houseList.length === 0) {
console.log("沒有居住房舍可以刪除");
} else {
this.houseList.shift();
console.log("居住房舍已刪除");
}
}
createCastle() {
if (this.stoneCounts < 650) {
console.log("石頭不足,無法建造城堡\n");
} else {
console.log("石頭充足,已建造城堡\n");
this.castleList.push(new Castle(this));
this.stoneCounts -= 600;
}
}
removeCastle() {
if (this.castleList.length === 0) {
console.log("沒有城堡可以刪除");
} else {
this.castleList.shift();
console.log("城堡已刪除");
}
}
gatherWood() {
if (this.villagerList.length === 0) {
console.log("沒有村民可用\n");
} else {
console.log("村民數量足夠,開始砍樹\n");
this.woodCounts += 100;
}
}
gatherFood() {
if (this.villagerList.length === 0) {
console.log("沒有村民可用\n");
} else {
console.log("村民數量足夠,開始採集食物\n");
this.foodCounts += 100;
}
}
gatherGold() {
if (this.villagerList.length === 0) {
console.log("沒有村民可用\n");
} else {
console.log("村民數量足夠,開始挖金礦\n");
this.goldCounts += 100;
}
}
gatherStone() {
if (this.villagerList.length === 0) {
console.log("沒有村民可用\n");
} else {
console.log("村民數量足夠,開始挖石礦\n");
this.stoneCounts += 100;
}
}
showResources() {
console.log("---當前資源---");
console.log("木頭: " + this.woodCounts);
console.log("食物: " + this.foodCounts);
console.log("黃金: " + this.goldCounts);
console.log("石頭: " + this.stoneCounts);
console.log("---當前建築數量---");
console.log("居住房舍: " + this.houseList.length);
console.log("城堡: " + this.castleList.length);
console.log("---當前單位數量---");
console.log("村民: " + this.villagerList.length);
console.log("遊俠: " + this.paladinList.length);
console.log("---完畢---\n");
}
}
行為的虛擬層親代:Command
/** @abstract */
class Command {
/** @param {Headquarters} headquarters */
constructor(headquarters) {
this.headquarters = headquarters;
}
/** @abstract */
executeCommand() { return; }
/** @abstract */
getName() { return; }
}
行為子代:CreateVillagerCommand
、RemoveVillagerCommand
、CreatePaladinCommand
、RemovePaladinCommand
、CreateHouseCommand
、RemoveHouseCommand
、CreateCastleCommand
、RemoveCastleCommand
、GatherFoodCommand
、GatherGoldCommand
、GatherStoneCommand
、GatherWoodCommand
、ShowResourcesCommand
(Command 物件)
class CreateVillagerCommand extends Command {
/** @param {Headquarters} headquarters */
constructor(headquarters) {
super(headquarters);
this.name = "生產村民";
}
/** @override */
executeCommand() {
this.headquarters.createVillager();
}
/** @override */
getName() {
return this.name;
}
}
class RemoveVillagerCommand extends Command {
constructor(headquarters) {
super(headquarters);
this.name = "刪除村民";
}
/** @override */
executeCommand() {
this.headquarters.removeVillager();
}
/** @override */
getName() {
return this.name;
}
}
class CreatePaladinCommand extends Command {
constructor(headquarters) {
super(headquarters);
this.name = "生產遊俠";
}
/** @override */
executeCommand() {
this.headquarters.createPaladin();
}
/** @override */
getName() {
return this.name;
}
}
class RemovePaladinCommand extends Command {
constructor(headquarters) {
super(headquarters);
this.name = "刪除遊俠";
}
/** @override */
executeCommand() {
this.headquarters.removePaladin();
}
/** @override */
getName() {
return this.name;
}
}
class CreateHouseCommand extends Command {
constructor(headquarters) {
super(headquarters);
this.name = "建造居住房舍";
}
/** @override */
executeCommand() {
this.headquarters.createHouse();
}
/** @override */
getName() {
return this.name;
}
}
class RemoveHouseCommand extends Command {
constructor(headquarters) {
super(headquarters);
this.name = "刪除居住房舍";
}
/** @override */
executeCommand() {
this.headquarters.removeHouse();
}
/** @override */
getName() {
return this.name;
}
}
class CreateCastleCommand extends Command {
constructor(headquarters) {
super(headquarters);
this.name = "建造城堡";
}
/** @override */
executeCommand() {
this.headquarters.createCastle();
}
/** @override */
getName() {
return this.name;
}
}
class RemoveCastleCommand extends Command {
constructor(headquarters) {
super(headquarters);
this.name = "刪除城堡";
}
/** @override */
executeCommand() {
this.headquarters.removeCastle();
}
/** @override */
getName() {
return this.name;
}
}
class GatherFoodCommand extends Command {
constructor(headquarters) {
super(headquarters);
this.name = "採集食物";
}
/** @override */
executeCommand() {
this.headquarters.gatherFood();
}
/** @override */
getName() {
return this.name;
}
}
class GatherGoldCommand extends Command {
constructor(headquarters) {
super(headquarters);
this.name = "挖金礦";
}
/** @override */
executeCommand() {
this.headquarters.gatherGold();
}
/** @override */
getName() {
return this.name;
}
}
class GatherStoneCommand extends Command {
constructor(headquarters) {
super(headquarters);
this.name = "挖石礦";
}
/** @override */
executeCommand() {
this.headquarters.gatherStone();
}
/** @override */
getName() {
return this.name;
}
}
class GatherWoodCommand extends Command {
constructor(headquarters) {
super(headquarters);
this.name = "砍樹";
}
/** @override */
executeCommand() {
this.headquarters.gatherWood();
}
/** @override */
getName() {
return this.name;
}
}
class ShowResourcesCommand extends Command {
constructor(headquarters) {
super(headquarters);
this.name = "顯示資源、建築與單位";
}
/** @override */
executeCommand() {
this.headquarters.showResources();
}
/** @override */
getName() {
return this.name;
}
}
對外窗口(Invoker):GUI
class GUI {
constructor() {
/** @type {Command[]} */
this.orders = [];
}
receivePlayerCommand(command) {
this.orders.push(command);
console.log("接收指令: " + command.getName() + " 時間:" + new Date().toISOString());
}
cancelPlayerCommand(command) {
this.orders.filter((item) => item !== command);
let index = -1;
for (let i = 0; i < this.orders.length; i++) {
const item = this.orders[i];
if (item.getName() === command.getName()) {
index = i;
break;
}
}
if (index >= 0) {
this.orders.splice(index, 1);
}
console.log("JSON.stringify(this.orders) " + JSON.stringify(this.orders))
console.log("取消指令: " + command.getName() + " 時間:" + new Date().toISOString());
}
executePlayerCommands() {
for (const command of this.orders) {
command.executeCommand();
}
}
}
測試,玩家嘗試建造房屋、城堡,生產村民、遊俠,採集木頭、食物、黃金、石頭,最後顯示資源與單位數量:rtsCommandSample
const rtsCommandSample = () => {
const headquarters = new Headquarters();
const createVillagerCommand = new CreateVillagerCommand(headquarters);
const createPaladinCommand = new CreatePaladinCommand(headquarters);
const createHouseCommand = new CreateHouseCommand(headquarters);
const createCastleCommand = new CreateCastleCommand(headquarters);
const gatherWoodCommand = new GatherWoodCommand(headquarters);
const gatherFoodCommand = new GatherFoodCommand(headquarters);
const gatherGoldCommand = new GatherGoldCommand(headquarters);
const gatherStoneCommand = new GatherStoneCommand(headquarters);
const showResourcesCommand = new ShowResourcesCommand(headquarters);
const gui = new GUI();
gui.receivePlayerCommand(createVillagerCommand);
gui.receivePlayerCommand(createPaladinCommand);
gui.receivePlayerCommand(gatherFoodCommand);
gui.receivePlayerCommand(gatherFoodCommand);
gui.receivePlayerCommand(gatherGoldCommand);
gui.receivePlayerCommand(gatherGoldCommand);
gui.receivePlayerCommand(createPaladinCommand);
gui.receivePlayerCommand(createHouseCommand);
gui.receivePlayerCommand(createHouseCommand);
gui.receivePlayerCommand(createHouseCommand);
gui.receivePlayerCommand(createHouseCommand);
gui.receivePlayerCommand(createHouseCommand);
gui.receivePlayerCommand(gatherWoodCommand);
gui.receivePlayerCommand(createHouseCommand);
gui.cancelPlayerCommand(createHouseCommand);
gui.cancelPlayerCommand(createHouseCommand);
gui.receivePlayerCommand(createCastleCommand);
gui.receivePlayerCommand(gatherStoneCommand);
gui.receivePlayerCommand(gatherStoneCommand);
gui.receivePlayerCommand(gatherStoneCommand);
gui.receivePlayerCommand(gatherStoneCommand);
gui.receivePlayerCommand(gatherStoneCommand);
gui.receivePlayerCommand(gatherStoneCommand);
gui.receivePlayerCommand(gatherStoneCommand);
gui.receivePlayerCommand(gatherStoneCommand);
gui.cancelPlayerCommand(gatherStoneCommand);
gui.receivePlayerCommand(createCastleCommand);
gui.receivePlayerCommand(showResourcesCommand);
gui.executePlayerCommands();
}
rtsCommandSample();
Command 模式是十分常見,將「行為請求者」與「行為執行者」切開來,避免兩者過度耦合,增加開發上的彈性。
但是缺點十分明顯,程式碼為了實踐分離目的,需要增加許多的程式碼,同時增加程式的複雜度。部份文章指出為了實踐設計模式會增加繁雜的設計、複雜度等等,今天總算體驗到了。
明天將介紹 Behavioural patterns 的第三個模式:Interpreter 模式。