2012-03-01 38 views
0

我剛纔讀過的an article,說一個例子:子類耦合和.NET

子類耦合。當一個基類型(通常是類)有一些擴展它的派生類型時,其他類型理想情況下應該只知道基類型。如果所有的子類型共享相同的公共接口(從基類型繼承的公共成員,爲每個子類中的不同行爲而被覆蓋),那麼外部的「客戶端」類型可以將它們全部視爲基類。如果不是這樣,如果客戶端類型知道存在的子類型的細節,那麼這是與有問題的多態結構耦合的子類。

具體而言,最後一行表示「如果客戶端類型知道存在的子類型的詳細信息...」。在.NET中,如果我使用WebRequest.Create("ftp://...");,那麼我知道將返回一個FtpWebRequest,並且我可以更改FtpWebRequest子類特有的屬性,例如UseBinary屬性。除非我有關於WebRequest的子類型的具體知識,否則我無法做到這一點,所以在我看來,這是子類耦合的情況,並且是不好的設計。

我很難相信這是代表.NET框架開發人員的糟糕設計,而是想象我對上述內容的理解有些過時。有人能夠解釋爲什麼我在.NET中提供的示例不是子類耦合的示例嗎?

回答

1

我會說這取決於。很多時候你不想在conrete類型上工作,比如你的FtpWebRequest,因爲這會讓你聯想到這種類型。如果您改爲使用名爲IRequestIWebRequest的接口,那麼您將不會與這些接口的具體實現耦合,這意味着在大多數情況下測試您的代碼會更容易,並且您將不那麼痛苦ftp到其他協議,只要它們符合你使用的接口。但是如果你正在做一件非常簡單的事情,那麼可能不需要在接口創建的額外抽象層中加入。

簡單的例子:

public interface IDoSomething { void DoSomething(); } 
public class DoSomethingA { public void DoSomething(); } 
public interface DoSomethingB { public void DoSomething(); } 

public class UseDoSomething 
{ 
    public UseDoSomething(IDoSomething do) { do.DoSomething(); } 
} 

如果您在類UseDoSomething參加了混凝土類型之一; DoSomethingADoSomethingB,那麼您會更緊密地實現該實現。通過我提供的示例,您可以自由使用​​的任何實現作爲UseDoSomething的輸入,這對未來很有用,並且使測試更加容易。正如你可能意識到一切都取決於你的要求等等。也許你必須使用具體類型,因爲你需要訪問該類型的特定事物,那麼這樣做可能很好。

我是否讓自己清楚?