我正在尝试将SOLID原则应用于我的项目,并且不确定如何处理以下场景:
我有一个界面:
IService
和实现接口的类
Service : IService
IService
中有很多方法,对于我的项目,我现在需要更新其中一种方法的功能,我们称之为method1
。
我对SOLID的理解是,我不应该更新method1
,而是创建一个扩展Service
(ServiceV2
)并覆盖method1
我的问题是,ServiceV2
只应展开Service
,还是需要实施界面IService
,然后展开Service
并覆盖method1
仅?
我问的主要原因是因为如果它实现IService
这会影响我的依赖注入(简单的Injector),因为我只能注册一个实现IService
的类
我认为我不会制作全新的IServcieV2
和ServiceV2
,因为这会失去IService
和IServicev2
之间的关系
另外,如果它只扩展Service
,我还在实现依赖倒置,因为新类没有直接实现接口,但我认为它是间接的?
答案 0 :(得分:1)
如果Service
实施IService
而Service2
来自Service
,那么Service2
会自动实施IService
,因为仅IService
为特定目的定义可行类的部分签名。然后使用此类或自由签名定义来创建一个类型,该类型又定义object
个成员。
签名不会通过继承而改变。它只能扩展。 这基本上是你唯一应该使用继承的东西:
如果Service2.Method1()
的可见行为与Service.Method1()
的可见行为不同,则表示Service2
的可见行为与Service的可见行为。在这种情况下,您不应使用继承,而应使用实现IService
的新类。因为在这种情况下它是不同的服务。
让我举一个具体的例子,虽然在不同的背景下:
技术上,正方形是矩形的特殊情况,意味着Square : Rectangle
。但是,如果方形的长度改变其宽度也会改变。对于矩形不是这种情况。因此,如果您有List<Rectangle>
包含常规Rectangle
以及Square
个对象,那么您可以将Square
定义为Rectangle
的子项,你会有不同的可见行为。因此,Square
不能成为Rectangle
的孩子,因为您无法使用Rectangle
代替Square
。所以Square : Rectangle
是假的。您可以同时实现一个接口IGeometry
,将Length
和Width
定义为属性,并在Rectangles
中同时使用Squares
和List<IGeometry>
。接口不指定行为。只是签名。
如果您有IConfigService
,您同样会将课程FileConfigService
和DatabaseConfigService
定义为FileConfigService : IConfigService
和DatabaseConfigService : IConfigService
,并让您的课程将其保留为{{因为他们不必关心任何类型的实现细节 - 他们只需要知道存在几个方法和属性。这也是为什么你为每个'目的'创建一个界面而不是为一切创建一个大的界面。为什么Interfaces只定义公共成员。
这基本上是大多数SOLID归结为的。
如果您只为IConfigService
实施添加功能,则只更改此类。没有什么可以阻止你。
虽然你有一些类似于现有和正在运行的系统所依赖的web服务,但这是一个不同的故事 - 在这种情况下,我会看看版本控制。