在 97 Things Every Programmer Should Know 一書中提到:
雖然在一般遇到的案例裡,使用 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();
}
}