如何设计可向连接设备发送开关命令的通用遥控器类结构
多设备通用遥控器实现方案
你直接排除继承实现的思路是完全正确的:继承描述的是is-a(是一个)的从属关系,让电视、灯继承遥控器,等于逻辑上认定「电视是一个遥控器」,完全不符合实际场景。遥控器和设备是has-a(持有/控制)的关联关系,用组合的方式实现就可以达到你要的效果。
核心实现逻辑
- 所有被控制的设备(TV、Light、Xbox等)自己维护内部的
isOn状态,对外暴露统一的turnOn()、turnOff()方法供外部调用 - 遥控器实例内部维护一个已接入设备的列表,提供设备注册入口
- 调用遥控器的开/关机方法时,遍历列表内所有已注册设备,挨个调用设备对应的开/关机方法即可
注:你给出的使用示例省略了「设备接入遥控器」的必要步骤——遥控器不可能凭空感知到所有创建出来的设备实例,显式注册需要控制的设备才是合理设计,否则会出现拿卧室遥控器开了客厅灯的混乱情况。
完整代码实现
首先实现各个设备类,每个设备自己管理状态:
class TV { constructor() { this.isOn = false } turnOn() { this.isOn = true } turnOff() { this.isOn = false } } class Light { constructor() { this.isOn = false } turnOn() { this.isOn = true } turnOff() { this.isOn = false } } class Xbox { constructor() { this.isOn = false } turnOn() { this.isOn = true } turnOff() { this.isOn = false } }
然后实现遥控器类:
class Remote { constructor() { // 存储所有已接入的可控设备 this.deviceList = [] } // 设备接入方法 addDevice(device) { // 简单校验,只接入符合接口规范的设备,避免调用时报错 if (typeof device.turnOn === 'function' && typeof device.turnOff === 'function') { this.deviceList.push(device) } } // 向所有接入设备发送开机命令 on() { this.deviceList.forEach(device => device.turnOn()) } // 向所有接入设备发送关机命令 off() { this.deviceList.forEach(device => device.turnOff()) } }
使用效果
const tv = new TV() tv.isOn // false const light = new Light() light.isOn // false const xbox = new Xbox() xbox.isOn // false const remote = new Remote() // 把需要控制的设备接入遥控器 remote.addDevice(tv) remote.addDevice(light) remote.addDevice(xbox) remote.on() tv.isOn // true light.isOn // true xbox.isOn // true
这种实现的扩展性很强,后续你要加新的可控设备(比如空调、投影仪),只要给新设备实现相同的turnOn/turnOff方法,不需要修改遥控器的任何代码,直接调用addDevice接入就能被控制。
内容的提问来源于stack exchange,提问作者TryingToLearn
相关产品推荐
相关产品推荐

