2012-03-01 34 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的输入,这对未来很有用,并且使测试更加容易。正如你可能意识到一切都取决于你的要求等等。也许你必须使用具体类型,因为你需要访问该类型的特定事物,那么这样做可能很好。

我是否让自己清楚?