June 21, 2006 Uncategorized

Why Use Private or Protected?

Is there ever a good case to use private or protected classes?

Is there ever a good case to use protected virtual/abstract members?

I think the answer is no, most of the time, to both questions.

Why?

I value unit testing, testability, composition over inheritance, and the single responsibility principle more than encapsulation.

If a set of members deserves to be its own class then it should be directly unit tested.  Protected classes could be tested by unit tests that are in the same assembly as the test subject.  I do not think this is a best practice: housing unit tests in the same assembly as the production code.  What is driving the desire to hide the type with private or protected?  The only answer I have ever heard was to prevent a developer using the type when they should not.  This is a smell to me.  It smells like the API design does not make clear to the consumer how to do what they want to do.  If it was they would not be using classes that they should not be.  If the class was in a namespace that a consumer had no reason to be using/importing they will be unlikely to use it.  It could even be placed in an assembly that the consumer would have no reason to reference.  Beyond that it could even be obfuscated after having been unit tested.  Every one of these solutions simply increases the effort a consumer will have to go to to even know about the type yet alone utilize it.  The best solution is make it easy for the consumer to know what to do.

Protected members only come into play when sub-classing a base class: inheritance (some people are more specific and call this implementation inheritance, not to be confused with interface inheritance).  Excluding edge cases (like CollectionBase and DictionaryBase) the only reason I have seen presented for using inheritance is to implement the Template Method pattern (also know as the Hollywood pattern).  I think a better solution to the problem that the Template Method pattern is trying to solve uses composition over inheritance.  Use the refactoring Extract Class on all the methods that are protected virtual/abstract in the base class and Extract Interface on the extracted class.

TemplateMethod Arrow Composition

This is a much easier solution to unit test.  It is easier to unit test ControlFlow than TemplateBase.  It is also much easier to unit test MySpecializer than MyTemplate.  The situation gets more complicated if you introduce virtuals (virtual in C#, overrideable in VB.NET)not just pure virtuals (abstract in C#, mustoverride in VB.NET).  A sub-class author can not know for certain if they should call on the base classes member they are overriding: base.DoIt().  Nor can they be sure when they should call it if they determine that they should call it (i.e. should it be called first, last, or somewhere in the middle).  The sub-class author will have to read the source code of the base class to figure this out.  This can cause maintenance issues for the base class author as well.  The base class author needs to understand when each of the sub-classes is calling the base method from their override.  If the base class author does not account for this bugs can easily be introduced.  Composition over inheritance provides an easier solution to maintain than the Template Method pattern for both the base class and sub-class authors.  The Template Method pattern smells to me of breaking the single responsibility principle.   In my experience it may not start out that way but it usually ends up that way.

16,216 Total Views

5 to “Why Use Private or Protected?”

Trackbacks/Pingbacks

  1. jokiz's blog says:

    Encapsulation vs Testability…

    Reference articles: Why use private or protected Testability I am fond of Rocky Lhotka ‘s CSLA framework…

  1. Tim says...

    Is there ever a good case to use protected virtual/abstract members?

    Yes, if you’re building a framework where your classes are meant to be extended. Certain functions you want to make virtual so that they can be overwritten and called. If they are not virtual, they can be overwritten with “new” but not called.

  2. jflowers says...

    I agree, a framework is a good case to use protected virtual/abstract members.

  3. Chris Brown says...

    I agree that people tend to over-use inheritance when an association would be more appropriate. However, saying that private/protected should not be used is a gross over-simplification.

    Private/protected have their place in a rounded design and infact they are used extensively throughout the .NET framework.

    “Ah!”, I hear you say, “what about unit testing?”. Well, only the public interface needs testing as this is the only part that can be called directly. All other methods are called indirectly. “But then it is not clear where an exception originated” – true but typically a private or protected methods are called as a child of a public operation – hence this indirection is no big deal.

    Dropping private/protected from your toolbox means you are effectively handicapping yourself unnecessarily.

    (PS. Singleton, prototype, builder – I felt I should mention a few GoF patterns!)

  4. jflowers says...

    Chris,
    I guess that part I having trouble with is: if it the code was important enough to create a new class for isn’t it important enough to test directly?

    The point of private and protected classes is to hide theme from developers that you do not want using them. There are other ways to hide them from those developers, like packaging or namepsaces. So if it is important to unit test them directly and hide them how can this be accomplished? That is what I am trying to communicate.

    P.S. Observer, Proxy, Adapter. :-P

  5. jokiz's blog says...

    Encapsulation vs Testability…

    Reference articles: Why use private or protected Testability I am fond of Rocky Lhotka ‘s CSLA framework…

Leave a comment

*

here