[英]Is interface-segregation principle about classes or objects?
提醒(來自Wiki ):
接口隔離原則 (ISP)指出,不應強迫任何客戶端依賴其不使用的方法。
現在來看我的例子。
這是我可變的實體。 它可以從某處進行編輯,並且可以通過只讀界面通知更改:
interface ICounter
{
event Action<int> NewNumber;
}
class Counter : ICounter
{
public event Action<int> NewNumber;
int number = 0;
public void IncrementAndSend(int x)
{
number += x;
if (NewNumber != null) NewNumber(number);
}
}
這是使用它的傳輸層中的類。 查看注入的兩種變體( Attach_1
和Attach_2
)以及我的假設如下:
class OneToManyRouter
{
IEnumerable<Counter> _destinations;
public OneToManyRouter(IEnumerable<Counter> destinations)
{
_destinations = destinations;
}
// 1
public void Attach_1(ICounter source)
{
source.NewNumber += (n) =>
{
foreach (var dest in _destinations) dest.IncrementAndSend(n);
};
}
// 2
public void Attach_2(Counter source)
{
source.NewNumber += (n) =>
{
foreach (var dest in _destinations) dest.IncrementAndSend(n);
};
}
}
ICounter
接口過多。 ISP既不是關於類也不是對象,而是嚴格地關於接口,特別是關於接口設計。 該原理旨在阻止在單個接口中對半相關方法進行分組,以避免用戶僅需要這些方法的子集即可將其余方法實現為空函數(拋出NotImplementedException
或將其字面保留為空: { }
) 。 因此,更容易實現更一致的類並更有效地使用接口。
在您的示例中,您將Counter
類與ICounter
接口結合在一起,而這種方式與ISP概念沒有直接關系:
- ISP是關於真實對象的。 您不得對傳入參數使用“過多”引用。
這部分是正確的(如果我正確地解釋“過多”的概念)。 但是,就像我提到的那樣,ISP 並不是關於如何與真實對象進行交互,而是關於如何定義有用的接口。
- ISP是關於類的。 如果您的類已在某個地方使用完整接口,則無需在特定方法中限制引用類型。 在此示例中,ICounter接口過多。
這是不正確的。 如果您創建對具體類而不是接口的依賴,則該類實現接口的事實並不意味着任何事情。 請記住,該接口通過使組件依賴合同而不是將來可能更改的特定實現,來提供程序各個部分的解耦。 通過使用具體的類,您將失去這種好處。 同樣,這並不完全與ISP概念相關。
- 從SOLID原則的角度來看,這種架構是完全錯誤的(那為什么呢?)。
從強調SOLID原則的體系結構角度來看,我建議對ICounter
而不是Counter
依賴,並建議將IncrementAndSend
作為接口定義的一部分。
我認為最好將IncrementAndSend方法添加到接口,並使類OneToManyRouter依賴於IEnumerable <ICounter>。 我認為這不是ISP違規,因為NewNumber事件操作和IncrementAndSend方法是嚴格相關的。 希望它能對您有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.