React组件设计原则-里氏替换原则 (LSP)

里氏替换原则 (LSP)

使类可替代子类

LSP 声明任何子类都应该可以替代其基类。[9]这意味着如果 B extendsA,那么我们应该能够在我们使用 A 的任何地方使用 B,而无需改变任何功能。我会直言不讳:我们只是没有真正在 React 中使用它。如今,无论如何,所有代码都应该使用类上的钩子来编写,因此类在现代 React 代码中的作用应该非常小。本节为后代而存在,但这肯定是应用于前端设计的不太相关的原则之一。[10]

为了说明这个原则,假设我们有一些基类,Vehicle它有一个附加到它的方法,它会发出汽车引擎的噪音。我们可以扩展一个由此调用的类,这很好,因为汽车有引擎噪音。但是,如果通过扩展创建,我们必须隐藏此方法,因为自行车没有引擎噪音,因此如果有人尝试调用,我们将抛出错误。engineNoise()CarBicycleVehicleengineNoise()engineNoise()Bicycle

class Vehicle {
  constructor(wheels){
    this.wheels = wheels;
  }

  engineNoise(){
    console.log("VROOM VROOM");
  }
};

class Car extends Vehicle {
  numWheels(){
    console.log(this.wheels);
  }
};

class Bicycle extends Vehicle {
  numWheels(){
    console.log(this.wheels);
  }

  // Bicycle has no engine, therefore we must throw an error
  // if someone attempts to access this property on a bicycle.
  engineNoise(){
    throw new Error("I have no engine.")
  }
}

function makeVehicleEngineNoise(vehicle){
  vehicle.engineNoise();
}

const car = new Car(4);
const bicycle = new Bicycle(2);

makeVehicleEngineNoise(car); // "VROOM VROOM!"
makeVehicleEngineNoise(bicycle); // ERROR: I have no engine.

如果我们尝试用,的子类调用,我们会得到一个错误(我们需要添加一个错误,因为我们不希望人们能够在自行车上调用)。这意味着我们无法替换with的每个实例并保持相同的功能。如果我们想这样做,我们将需要改变我们的类,使其只包含所有可能的子类都具有的属性/方法。例如,如果我们假设每辆车都有轮子,我们可以修改我们的类并安抚 LSP:makeVehicleEngineNoise()VehicleBicycleengineNoiseVehicleBicycleVehicleVehicle

class Vehicle {
  constructor(wheels){
    this.wheels = wheels;
  }

  numWheels(){
    console.log(this.wheels);
  }

};

class Car extends Vehicle {
  engineNoise(){
    console.log("VROOM VROOM");
  }
};

class Bicycle extends Vehicle {

  sayFrameMaterial{
    console.log("I am made from carbon fibre!")
  }
}

function sayNumWheels(vehicle){
  vehicle.numWheels();
}

const car = new Car(4);
const bicycle = new Bicycle(2);

sayNumWheels(car); // 4
sayNumWheels(bicycle); // 2

如果您从一个类扩展,请确保基类是通用的,因为它是每个子类的真实表示。

相关标签:
  • React组件设计原则
0人点赞

发表评论

当前游客模式,请登陆发言

所有评论(0)