Search code examples
.netsubclasscoupling

Subclass Coupling and an example in .NET


I have just been reading an article that says:

Subclass coupling. When a base type (usually class) has a number of derived types that extend it, other types should ideally only know about the base type. If all the subtypes share the same public interface (the public members inherited from the base type, overwritten for different behavior in each subclass), then outside "client" types can treat them all the same, as if they were the base class. If this is not so, if a client type knows specifics about the subtypes that exist, then this is subclass coupling to the polymorphic structure in question.

Specifically, the last line says that "if a client type knows specifics about the subtypes that exist...". In .NET, if I use the WebRequest.Create("ftp://..."); then I know that an FtpWebRequest will be returned, and that I can change properties that are specific to the FtpWebRequest subclass, such as the UseBinary property. I wouldn't be able to do that unless I had specific knowledge about the subtype of WebRequest, so in my mind, this is a case of subclass coupling and is bad design.

I struggle to believe that this is bad design on behalf of the .NET framework developers, and instead imagine that my understanding of the above is a little off. Would someone be able to explain why the example I have provided in .NET is not an example of subclass coupling?


Solution

  • I would say that it depends. A lot of the time you don't want to work on the conrete types, like your FtpWebRequest, since this makes you coupled to that type. If you instead work against an interface called IRequest or IWebRequest you will not be as coupled to the concrete implementation of those interfacet which means that it will be easier to test your code, most of the time, and you will have less pain to going from ftp to some other protocol as long as they conform to the interface you are using. But if you are doing something really simple there might be no need to put in the extra abstraction layers that the interfaces create.

    Simple example:

    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(); }
    }
    

    If you in the class UseDoSomething took in one of the concrete types; DoSomethingA or DoSomethingB, you would have tighter coupling towards that implementation. With the example I provided you are free to use any implementation of IDoSomething as input to UseDoSomething which is great for the future and also makes it easier to test. As you might realise everything depends on you requirements etc. Maybe you must use the concrete type since you need to access that specific thing of the type, then it might be fine to do so.

    Do I make myself clear?