固体:SRP + ISP

SOLID : SRP + ISP

我正在尝试理解 SOLID 原则。我觉得我理解里氏替换原则,但我对其他的有一些问题。

一个例子。我有两个接口:Enginecar stereo。 问题是:对于一辆汽车,我们有 6 副眼镜。

所以,我的车实现了接口 EngineCar Stereo

但是对于 6 副眼镜,我应该实施它们,还是应该将它们放在一组眼镜上,因为我知道有 4 副可以向上或向下的横向眼镜和 2 个挡风玻璃(glasses 继承由两者)。

第一个的问题是,我无法实现 4 次相同的眼镜。

所以第二个在我看来不错,但我担心会破坏 SRP,我不确定 "Responsibilities" 到底是什么。

这实际上取决于预期用途,但让我们以汽车功能域(当场发明)为例。

您的实现 class 将实现 IMotor(Tesla D 有两个电机)、IEntertainmentCentre(希望有一个)、IGlassSurface(在 SUV 中可能是很多)。在每个界面中,您将指定要寻址的 motor/glass-surface,例如:IGlassSurface.Operate(glassSurfaceId, direction, distance).

正确的设计实践是

code to interface rather than class.

根据这个原则,我建议使用像 IWindowISurfaceIWindShield 这样的接口,层次结构如下

interface ISurface
{
  //surface specific properties which ideally should be DI-ed
  public SurfaceType SurfaceType {get; set;}
  public decimal Opacity {get;set;}
  public decimal Thickness {get; set;}
}

interface IWindow:ISurface
{
  //Window behavior specific properties and methods
  public void lowerWindow();
  public WindowHeight WindowLevel(){get;set;}
  public void shutWindow();
  // ...and more such window specific behavior
}

interface IWindShield:ISurface
{
  //WindShield behavior specific properties and methods
  public bool IsFogged(){get;set;}
  public bool IsClean(){get;set;}
  // ...and more such window specific behavior
}

最后,在组装具有所有功能的汽车时(大概使用构建器模式),您可以在类型为 ISurface 的汽车 class 中有一个数组,如下所示

class Car
{
   string carName;
   Engine carEngine;
   Stereo carStereo;
   List<ISurface> carGlasses;
   .....
   // other Car parts
   // this is a typical builder pattern example
}

这是使用 CarBuilder 类型构建的 class 说 MyCarBuilder 其中

interface CarBuilder
{
  public Car MyCar {get; set;}
  void AddEngine();
  void AddStereo();
  void AddGlasses();// this is what works on adding ISurface List items
  // and other car building methods
}

真正的建设者class

class MyCarBuilder:CarBuilder
{
    //... implements all methods of building your custom car
}