Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/436.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 项目之间的类继承_Javascript_Oop - Fatal编程技术网

Javascript 项目之间的类继承

Javascript 项目之间的类继承,javascript,oop,Javascript,Oop,我正在管理一个小产品线的UI。所有这些产品都是或多或少具有相同模块的硬件,但作为一个单元本身,可能具有额外的全局功能。这些全局功能与这些模块交互,通常为多个模块提供相同的功能。我正努力用逻辑类继承来维护OOP方法,但有时似乎不可能不复制粘贴某些功能 在本例中,我用LightSwitch说明了该情况。产品A和产品B都可以有一个灯开关产品B也有一个报警开关产品B的光开关和报警开关的实现也需要一个功能完全相同的定时器产品A不支持计时器 我在这里看到的唯一解决方案是跨模块复制粘贴。我想不出任何其他方法可

我正在管理一个小产品线的UI。所有这些产品都是或多或少具有相同模块的硬件,但作为一个单元本身,可能具有额外的全局功能。这些全局功能与这些模块交互,通常为多个模块提供相同的功能。我正努力用逻辑类继承来维护OOP方法,但有时似乎不可能不复制粘贴某些功能

在本例中,我用
LightSwitch
说明了该情况。产品A产品B都可以有一个
灯开关
产品B也有一个
报警开关
产品B的
光开关
报警开关
的实现也需要一个功能完全相同的
定时器产品A不支持计时器

我在这里看到的唯一解决方案是跨模块复制粘贴。我想不出任何其他方法可以在不破坏模型的情况下扩展它

// Common components

class Switch {
  constructor() {
    this.state = false;
  }
  open() {
    this.state = true;
  }
  close() {
    this.state = false;
  }
}

class LightSwitch extends Switch {
  constructor() {
    super();
    this.colour = "white";
  }
  changeColour(colour) {
    this.colour = colour;
  }
}

// Product A 

class LedSwitch extends LightSwitch {
  constructor() {
    super();
    this.blink = false;
  }
  blink(state) {
    this.blink = state;
  }
}

// Product B
// AlarmSwitch and ProductBLightSwitch both need a "timer"

class AlarmSwitch extends Switch {
  constructor() {
    super();
    this.sound = "alarm.wav";
    this.timer = 5000;
  }
  changeSound(sound) {
    this.sound = sound;
  }
  resetTimer() {
    this.timer = 0;
  }
}

class ProductBLightSwitch extends LightSwitch {
  costructor() {
    super();
    this.timer = 5000;
  }
  resetTimer() {
    this.timer = 0;
  }
}

可以考虑将“代码>//公共组件< /代码>重构和分解为(i)基于行为的混合/特征,并将(ii)类型的外壳类只负责类型签名,并将已经存在的代码粘贴在一起(通过组合和继承进行代码重用)。同时,人们可能更关心如何访问/隐藏对象的当前状态。这样一种方法将在下面的OP的重构示例代码中演示

//通用组件
变量
withSerializableTypeProxy=(函数(){
函数到字符串(类型){
返回JSON.stringify(type);
}
函数值(类型){
返回JSON.parse(JSON.stringify(type))
}
设defineProperty=Object.defineProperty;
返回函数特性(stateValue){
常数
复合类型=此;
defineProperty(复合类型,'toString'{
值:(()=>toString(stateValue))
});
定义属性(复合类型,'valueOf'{
值:(()=>valueOf(stateValue))
});
};
}());
带有ChangeableColorProxy(stateValue)的函数{
常数
复合类型=此;
compositeType.changeColor=((colorValue)=>stateValue.color=colorValue);
Object.defineProperty(复合类型,'color'{
可枚举:正确,
获取:(()=>stateValue.color)
});
stateValue.color='white';//设置默认值。
}
类开关{
构造函数(stateValue){
stateValue=((stateValue!=null)和&(typeof stateValue=='object')&&stateValue)|{};
stateValue.isOpen=true;
常数
开关类型=此;
调用(switchType、stateValue);
switchType.open=(()=>stateValue.isOpen=true);
switchType.close=(()=>stateValue.isOpen=false);
Object.defineProperty(此“等参线”{
可枚举:正确,
获取:(()=>stateValue.isOpen)
});
}
}
类光开关扩展开关{
构造函数(stateValue){
stateValue=((stateValue!=null)和&(typeof stateValue=='object')&&stateValue)|{};
超级(状态值);
withChangeableColorProxy.call(this,stateValue);
}
}
变量
lightSwitch=(新的lightSwitch);
控制台日志(“lightSwitch:,lightSwitch”);
log(((lightSwitch的lightSwitch实例)?,(lightSwitch的lightSwitch实例));
log(((lightSwitch instanceof Switch)?,(lightSwitch instanceof Switch));
log(((lightSwitch+“”):“,(lightSwitch+“”));
log(“lightSwitch.toString():”,lightSwitch.toString());
log(“lightSwitch.valueOf():”,lightSwitch.valueOf());
log(“Object.keys(lightSwitch):”,Object.keys(lightSwitch));
log(“lightSwitch.isOpen:”,lightSwitch.isOpen);
log(“lightSwitch.close():”,lightSwitch.close());
log(“lightSwitch.isOpen:”,lightSwitch.isOpen);
log(“lightSwitch.open():”,lightSwitch.open());
log(“lightSwitch.isOpen:”,lightSwitch.isOpen);
log(“lightSwitch.color:,lightSwitch.color”);
log(“lightSwitch.changeColor('pink'):”,lightSwitch.changeColor('pink'));
log(“lightSwitch.color:,lightSwitch.color”);
log(“lightSwitch.changeColor('light-blue'):”,lightSwitch.changeColor('light-blue'));
log(“lightSwitch.color:,lightSwitch.color”)

。作为控制台包装器{max height:100%!important;top:0;}
不要被迫将所有内容都转换为一个范例。使用您可以使用的任何语言特性来编写自然的解决方案。也许是一种组合方法,您可以在其中创建一个单独的
计时器
对象,该对象提供通用计时器功能,如
reset()
,并在计时器关闭时接收一个回调函数,用于任何需要的特定功能。然后,任何需要计时器的类都可以有自己的计时器实例。我建议您搜索
偏好组合而不是继承。有些情况下使用继承,有些情况下使用组合。我知道你正在经历一个“遗产地狱”的案子。你可以试着自然地思考问题。如果你认为Y是X是不自然的,那么也许你可以从Y的角度考虑更多,和X.有关系,即使你在你的问题中使用“某物有其他东西”,而“某物是其他东西”。也许AlarmSwitch是一个LightSwitch,但也许ProdA不是一个LightSwitch,而是一个LightSwitch。当有意义的时候,我会把东西移动到子组件中。在这种情况下,
定时器
就是一个很好的例子。计时器可以独立存在。但就其本身而言,它什么也不做。在这种情况下,它需要连接到
报警开关
报警开关
。问题是,对于这两个类,它以完全相同的方式连接起来……我绝对不会使用inher