雖然在一般遇到的案例裡,使用 if - then - else 比多型更實用些,但絕大多數用 polymorphism 的寫作風格會讓程式碼更精簡、更易讀,且更少脆弱的程式碼。所以在我們的程式碼裡,要是錯過使用 polymorphism 的機會,便會逐漸增加 if - then - else 敘述句的數量。試試 command pattern 吧
假設我有一個機器人物件,他會執行前進、後退、左轉與右轉,這四種指令
package albert.practice.designpattern.command; import lombok.AllArgsConstructor; import lombok.Data; import lombok.extern.slf4j.Slf4j; @AllArgsConstructor @Data @Slf4j public class Robot { private String robotName; public void goAhead() { log.debug(robotName + " 前進 !"); } public void turnLeft() { log.debug(robotName + " 左轉 !"); } public void turnRight() { log.debug(robotName + " 右轉 !"); } public void turnBack() { log.debug(robotName + " 後退 !"); } }
另外建立一個 enumeration 來判斷,此次呼叫要執行哪一個指令
package albert.practice.designpattern.command; public enum CommandEnum { GO_HEAD, TURN_BACK, TURN_RIGHT, TURN_LEFT; }
建立機器人物件與執行指令如下:
package albert.practice.designpattern.command; public class RobotTestClient { public static void main(String[] args) { Robot robot = new Robot("瓦力"); RobotTestClient client = new RobotTestClient(); client.executeRobot(robot, CommandEnum.GO_HEAD); client.executeRobot(robot, CommandEnum.TURN_LEFT); client.executeRobot(robot, CommandEnum.TURN_RIGHT); } public void executeRobot(Robot robot, CommandEnum command) { if (CommandEnum.GO_HEAD == command) { robot.goAhead(); } else if (CommandEnum.TURN_BACK == command) { robot.turnBack(); } else if (CommandEnum.TURN_LEFT == command) { robot.turnLeft(); } else if (CommandEnum.TURN_RIGHT == command) { robot.turnRight(); } } }
在上述的程式碼就會發現,如果指令越來越多,就會有越來越多的 if-else 判斷式,此時就可以套用 command pattern
首先,先建立 Command interface
package albert.practice.designpattern.command; public interface Command { void execute(); }
然後,分別建立四個指令的 classes,並實作 Command interface
前進指令:
package albert.practice.designpattern.command; public class GoAheadCommand implements Command { private Robot robot; public GoAheadCommand(Robot robot) { super(); this.robot = robot; } @Override public void execute() { this.robot.goAhead(); } }
後退指令:
package albert.practice.designpattern.command;
public class TurnBackCommand implements Command {
private Robot robot;
public TurnBackCommand(Robot robot) {
super();
this.robot = robot;
}
@Override
public void execute() {
this.robot.turnBack();
}
}
向左轉指令:
package albert.practice.designpattern.command; public class TurnLeftCommand implements Command { private Robot robot; public TurnLeftCommand(Robot robot) { super(); this.robot = robot; } @Override public void execute() { this.robot.turnLeft(); } }
向右轉指令:
package albert.practice.designpattern.command; public class TurnRightCommand implements Command { private Robot robot; public TurnRightCommand(Robot robot) { super(); this.robot = robot; } @Override public void execute() { this.robot.turnRight(); } }
建立機器人物件與操作指令,程式修改如下:
package albert.practice.designpattern.command; public class RobotTestClient { public static void main(String[] args) { Robot robot = new Robot("瓦力"); new GoAheadCommand(robot).execute(); new TurnLeftCommand(robot).execute(); new TurnRightCommand(robot).execute(); } }