[英]c# interface segregation principle example confusion
我對編程很新,我很難理解如何有效地應用以下鏈接中顯示的原理(ATM一):
http://www.objectmentor.com/resources/articles/isp.pdf
基本上,它從一個不抱怨ISP(接口隔離原理)的設計開始,然后繼續將行為重構為不同的接口。
我的問題是: 我們不是使用接口來表達不相關(或不相關)抽象中的共同行為嗎?
在接口中封裝方法有什么意義,如果不是一個將與將要實現它們的類共享? 在哪種情況下,這可能被認為是有用的?
如果我們繼續該示例的行,則給出以下代碼:
public interface ITransaction
{
void Execute();
}
public interface IDepositUi
{
void RequestDepositAmount();
}
public class DepositTransaction : ITransaction
{
private IDepositUi depositUI;
public DepositTransaction(IDepositUi ui)
{
depositUI = ui;
}
public virtual void Execute()
{
/*code*/
depositUI.RequestDepositAmount();
/*code*/
}
}
public interface WithdrawalUI
{
void RequestWithdrawalAmount();
}
public class WithdrawalTransaction : ITransaction
{
private WithdrawalUI withdrawalUI;
public WithdrawalTransaction(WithdrawalUI ui)
{
withdrawalUI = ui;
}
public virtual void Execute()
{
/*code*/
withdrawalUI.RequestWithdrawalAmount(); /*code*/
}
}
public interface TransferUI
{
void RequestTransferAmount();
}
public class TransferTransaction : ITransaction
{
private TransferUI transferUI;
public TransferTransaction(TransferUI ui)
{
transferUI = ui;
}
public virtual void Execute()
{
/*code*/
transferUI.RequestTransferAmount();
/*code*/
}
}
public interface UI : IDepositUi, WithdrawalUI, TransferUI
{
}
據我所知,為了使用以前的設計,我們應該有類似的東西:
UI impui = new IMPLEMENTATIONUI(); // Some UI implementation
DepositTransaction dt = new DepositTransaction(Gui);
dt.Execute();
現在,我們不需要IMPLEMENTATIONUI實現每一種方法嗎? 如果是這樣,它不會打破SRP嗎?
我們不是使用接口來表達不相關(或不相關)抽象之間的共同行為嗎?
是的,在SOLID中,接口需要表達共同的行為。 您的交易界面就是一個極好的例子。 DepositTransaction和WithdrawlTransaction類都依賴於它。 ISP(接口隔離原則)希望您將其拆分,因為您可能需要將Transaction對象傳遞給函數來執行它。 所有SOLID原則都是設計的例如:
void ExecuteTransaction(Transaction transaction)
{
transaction.Execute();
}
請注意,此方法不依賴於Transaction接口。 這是依賴倒置。
如果您不創建此接口,則需要創建兩個不同的方法來執行WithdrawlTransaction或DepositTransaction; 相反,您可以使用ExecuteTransaction方法並傳入實現Transaction的任何內容。
ExecuteTransation(withdrawl_TransactionObject);
要么
ExecuteTransaction(deposit_TransactionObject);
或以后的未來:
ExecuteTransaction(unanticipatedNewTypeOf_TransactionObject);
現在,我們不需要IMPLEMENTATIONUI實現每一種方法嗎? 如果是這樣,它不會打破SRP嗎?
實現UI可能是用戶用來與軟件交互的內容。 用戶不會有單一責任,理論上他/她將不得不使用IMPLEMENTATIONUI類所需的所有接口。
我懷疑實現UI將實現所有接口,但它可能會使用所有這些接口來執行事務。 要解釋“Uncle Bob” Solid Principles,您的用戶界面應該充滿了易失性代碼,而您的界面應該是最不易變的。
是否有一個接口繼承了另外三個ISP違規?
public interface UI : IDepositUi, WithdrawalUI, TransferUI
{
}
答案是我們無法分辨。 這取決於客戶端是否依賴於整個界面。 如果是,那么這不是ISP違規。 如果客戶端不依賴於所有三種繼承接口,那么這是一個違規,因此客戶應該只取決於哪個接口(S) 確實需要上。
正如您所觀察到的那樣,它可能違反了其他一些原則,但這不屬於討論ISP的范圍。 但我不認為你應該創建那個組合界面。 關鍵是你可以保留較小的隔離接口。
我們可能很想在巨型接口和一個巨型類上創建,因為一個客戶端依賴於所有三個接口。 但是如果我們這樣做,另一個只需要提款或轉賬的客戶將被迫依賴於它不需要的更大的接口。
在現實生活中,這種事情變得失控,因為某人從像ITransactionService
這樣廣泛,模糊命名的界面開始,在您知道更多開發人員將廚房水槽扔進去之前。 在該示例中,接口更具體地命名。 這不會強制保持隔離,但它會有所幫助。 事先給他們這樣的特定名稱傳達了應該或不應該在其中的內容。 它建議開發人員預先計划以保持接口隔離。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.