public class AirConditioner {
public void turnOn() {
System.out.println("空调已开启");
}
public void turnOff() {
System.out.println("空调已关闭");
}
}
public class Television {
public void turnOn() {
System.out.println("电视已开启");
}
public void turnOff() {
System.out.println("电视已关闭");
}
}
客户端:
java复制代码
public class Application {
public static void main(String[] args) {
AirConditioner airConditioner = new AirConditioner();
Television television = new Television();
Scanner scanner = new Scanner(System.in);
while (true) {
String device = scanner.next();
if (device.equals("exit")) {
break;
}
String command = scanner.next();
if (device.equals("airConditioner")) {
if (command.equals("turnOn")) {
airConditioner.turnOn();
} else if (command.equals("turnOff")) {
airConditioner.turnOff();
}
} else if (device.equals("television")) {
if (command.equals("turnOn")) {
television.turnOn();
} else if (command.equals("turnOff")) {
television.turnOff();
}
}
}
}
}
public interface Receiver {
void turnOn();
void turnOff();
}
public class AirConditioner implements Receiver {
@Override
public void turnOn() {
System.out.println("空调已开启");
}
@Override
public void turnOff() {
System.out.println("空调已关闭");
}
}
public class Television implements Receiver {
@Override
public void turnOn() {
System.out.println("电视已开启");
}
@Override
public void turnOff() {
System.out.println("电视已关闭");
}
}
命令:
java复制代码
public abstract class Command {
protected Receiver receiver;
public void setReceiver(Receiver receiver) {
this.receiver = receiver;
}
public abstract void execute();
}
public class TurnOffCommand extends Command {
@Override
public void execute() {
receiver.turnOff();
}
}
public class TurnOnCommand extends Command {
@Override
public void execute() {
receiver.turnOn();
}
}
设备管理器:DeviceManager
java复制代码
public class DeviceManager {
private final Map<String, Receiver> devices;
private final Map<String, Command> commands;
private DeviceManager() {
devices = ImmutableMap.of(
DeviceEnum.AIR_CONDITIONER.getValue(), new AirConditioner(),
DeviceEnum.TELEVISION.getValue(), new Television()
);
commands = ImmutableMap.of(
CommandEnum.TURN_ON.getValue(), new TurnOnCommand(),
CommandEnum.TURN_OFF.getValue(), new TurnOffCommand()
);
}
public static DeviceManager getSingleton() {
return new DeviceManager();
}
public void execute(String device, String commandType) {
Receiver receiver = devices.get(device);
Command command = commands.get(commandType);
command.setReceiver(receiver);
command.execute();
}
}
客户端:
java复制代码
public class Application {
public static void main(String[] args) {
DeviceManager deviceManager = DeviceManager.getSingleton();
Scanner scanner = new Scanner(System.in);
while (true) {
String device = scanner.next();
if (device.equals("exit")) {
break;
}
String command = scanner.next();
deviceManager.execute(device, command);
}
}
}
2、当需求变化时
新增一个设备:洗衣机
新增一个命令:待机
2.1 新增代码
新增命令:
java复制代码
public class StandByCommand extends Command {
@Override
public void execute() {
receiver.standby();
}
}
新增设备:
java复制代码
public interface Receiver {
...
void standby(); // 新增方法
}
// 新增设备
public class Washer implements Receiver {
@Override
public void turnOn() {
System.out.println("洗衣机已开启");
}
@Override
public void turnOff() {
System.out.println("洗衣机已关闭");
}
@Override
public void standby() {
System.out.println("洗衣机已待机");
}
}
修改设备(新增方法):
java复制代码
public class AirConditioner implements Receiver {
...
@Override
public void standby() {
System.out.println("空调已待机");
}
}
public class Television implements Receiver {
...
@Override
public void standby() {
System.out.println("电视已待机");
}
}
修改设备管理器:
java复制代码
public class DeviceManager {
private final Map<String, Receiver> devices;
private final Map<String, Command> commands;
private DeviceManager() {
devices = ImmutableMap.of(
...
DeviceEnum.WASHER.getValue(), new Washer()
);
commands = ImmutableMap.of(
...
CommandEnum.STAND_BY.getValue(), new StandByCommand()
);
}
...
}
2.2 优点
之前写的代码,一行都没改动。只是通过新增代码,便实现了需求:
尽可能符合"开闭原则"。
各个设备、各个命令都很单一,尽可能符合"单一职责"。
四、进一步思考
1、省略对Command的建模可以吗?
省略后的伪代码:
java复制代码
public class DeviceManager {
...
public void execute(String device, String commandType) {
// 根据device找到对应的实体
Device realDevice = deviceMap.get(device);
// 每个device根据commandType执行不同的逻辑
realDevice.execute(commandType);
}
...
}
// 各个device都要实现这样的路由逻辑:
public void execute(String commandType) {
if ("turnOn".equals(commandType)) {
...
} else if ("turnOff".equals(commandType)) {
...
} else {
...
}
}