设计模式-命令模式和组合模式的综合应用
题目:使用组合命令模式实现多功能开关,让用户进行设置,可以同时控制教室的所有灯的开和关,并能控制风扇、空凋、多媒体投影仪设备的开和关。
思路:在之前的命令模式学习中,通常是对一种设备进行不同类型的操作,例如open\close
这时需要对多种不同设备进行相同的两种命令,就需要对各种设备进行抽象,抽象类Device, 各种设备则是Device的具体子类,Device通过两个操作接口,open,close。 而命令的抽象类为 Command,openCommand、closeCommand则是其具体子类,在实例化open/closeCommand时则传入Device参数,让Command与Device进行绑定,比如生成空调的开命令: openCommand(airCleaner);
题目中“同时控制所有灯”,这就表示一个Command可以操作多个灯Device,这时可以使用组合模式,额外新增 Device的一个具体子类 DevicePackage, 用于将多个Device组合在一起形成一个逻辑整体
在对DevicePackage进行close时,则对里面所有Device进行close操作, 控制所有灯的Command则与DevicePackage进行绑定
而最终Client使用的遥控器Controller,则需要设置 灯package、风扇、空调、多媒体的open/closeCommand 成员, 并且提供诸如 openAirCleaner、CloseAllLights…之类的操作
最终类图:
代码实现 : java
package hah;
import java.util.ArrayList;
public class Pro {
public static void main(String[] args) {
DevicePackage allLights; // 所有灯设备的集合
Device light, light2, blower, airCleaner, Multimedia;
// 初始化设备
allLights = new DevicePackage();
light = new Light();
light2 = new Light();
blower = new Blower();
airCleaner = new airCleaner();
Multimedia = new Multimedia();
allLights.addDevice(light);
allLights.addDevice(light2);
// 初始化命令
Command lightsOpenCommand, lightsCloseCommand, blowerOpenCommand, blowerCloseCommand, airOpenCommand,
airCloseCommand, multiOpenCommand, multiCloseCommand;
lightsOpenCommand = new DeviceOpenCommand(allLights);
lightsCloseCommand = new DeviceCloseCommand(allLights);
blowerOpenCommand = new DeviceOpenCommand(blower);
blowerCloseCommand = new DeviceCloseCommand(blower);
airOpenCommand = new DeviceOpenCommand(airCleaner);
airCloseCommand = new DeviceCloseCommand(airCleaner);
multiOpenCommand = new DeviceOpenCommand(Multimedia);
multiCloseCommand = new DeviceCloseCommand(Multimedia);
// 命令集成为多功能遥控
Controller controller = new Controller(lightsOpenCommand, lightsCloseCommand, blowerOpenCommand,
blowerCloseCommand, airOpenCommand, airCloseCommand, multiOpenCommand, multiCloseCommand);
controller.openAllLights();
controller.openBlower();
controller.openMulti();
controller.openAirCleaner();
controller.closeAllLights();
controller.closeBlower();
controller.closeMulti();
controller.closeAirCleaner();
}
}
class Controller {
private Command lightsOpenCommand, lightsCloseCommand, blowerOpenCommand, blowerCloseCommand, airOpenCommand,
airCloseCommand, multiOpenCommand, multiCloseCommand;
public Controller(Command lightsOpenCommand, Command lightsCloseCommand, Command blowerOpenCommand,
Command blowerCloseCommand, Command airOpenCommand, Command airCloseCommand, Command multiOpenCommand,
Command multiCloseCommand) {
this.lightsOpenCommand = lightsOpenCommand;
this.lightsCloseCommand = lightsCloseCommand;
this.blowerOpenCommand = blowerOpenCommand;
this.blowerCloseCommand = blowerCloseCommand;
this.airCloseCommand = airCloseCommand;
this.airOpenCommand = airOpenCommand;
this.multiCloseCommand = multiCloseCommand;
this.multiOpenCommand = multiOpenCommand;
}
public void openAllLights() {
lightsOpenCommand.execute();
}
public void closeAllLights() {
lightsCloseCommand.execute();
}
public void openBlower() {
blowerOpenCommand.execute();
}
public void closeBlower() {
blowerCloseCommand.execute();
}
public void openAirCleaner() {
airOpenCommand.execute();
}
public void closeAirCleaner() {
airCloseCommand.execute();
}
public void openMulti() {
multiOpenCommand.execute();
}
public void closeMulti() {
multiCloseCommand.execute();
}
}
abstract class Command {
protected Device device;
public abstract void execute();
}
class DeviceOpenCommand extends Command {
public DeviceOpenCommand(Device device) {
this.device = device;
}
@Override
public void execute() {
device.open();
}
}
class DeviceCloseCommand extends Command {
public DeviceCloseCommand(Device device) {
this.device = device;
}
@Override
public void execute() {
device.close();
}
}
abstract class Device {
public abstract void close();
public abstract void open();
}
class DevicePackage extends Device {
private ArrayList<Device> list = new ArrayList<Device>();
public void addDevice(Device device) {
list.add(device);
}
public void removeDevice(Device device) {
list.remove(device);
}
@Override
public void close() {
int index = 1;
for (Device device : list) {
System.out.print(index + "号");
device.close();
index++;
}
}
@Override
public void open() {
int index = 1;
for (Device device : list) {
System.out.print(index + "号");
device.open();
index++;
}
}
}
class airCleaner extends Device {
@Override
public void close() {
System.out.println("空调关了");
}
@Override
public void open() {
System.out.println("空调开了");
}
}
class Multimedia extends Device {
@Override
public void close() {
System.out.println("多媒体关了");
}
@Override
public void open() {
System.out.println("多媒体开了");
}
}
class Blower extends Device {
@Override
public void close() {
System.out.println("风扇关了");
}
@Override
public void open() {
System.out.println("风扇开了");
}
}
class Light extends Device {
@Override
public void close() {
System.out.println("灯关了");
}
@Override
public void open() {
System.out.println("灯开了");
}
}
运行结果:
1号灯开了
2号灯开了
风扇开了
多媒体开了
空调开了
1号灯关了
2号灯关了
风扇关了
多媒体关了
空调关了
上一篇: 全球唯二:西数蓝盘SSD扩容4TB 每天0.08次全盘写入
下一篇: 使用python写的一个小系统