固体:SRP + ISP
SOLID : SRP + ISP
我正在尝试理解 SOLID 原则。我觉得我理解里氏替换原则,但我对其他的有一些问题。
一个例子。我有两个接口:Engine
和 car stereo
。
问题是:对于一辆汽车,我们有 6 副眼镜。
所以,我的车实现了接口 Engine
和 Car 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.
根据这个原则,我建议使用像 IWindow
、ISurface
、IWindShield
这样的接口,层次结构如下
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
}
我正在尝试理解 SOLID 原则。我觉得我理解里氏替换原则,但我对其他的有一些问题。
一个例子。我有两个接口:Engine
和 car stereo
。
问题是:对于一辆汽车,我们有 6 副眼镜。
所以,我的车实现了接口 Engine
和 Car 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.
根据这个原则,我建议使用像 IWindow
、ISurface
、IWindShield
这样的接口,层次结构如下
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
}