6

The current code looks like this:

public class Details
{
    Public void Populate()
    {
         WriteChapterDetails();
    }

    public void WriteChapterDetails()
    {
       if ( includeHighDetails)        
       {
         \\Do something
       }

       if (includeLowDetails)
       {
         \\Do something
       }
    }
}

I now want to write a new class named HighDetails which will be copy of the Details class except I don't want it to go to the if (includeLowDetails) condition.

I am thinking of deriving a class from Details class like:

public class HighDetails()
{
  Public void Populate()
    {
         WriteChapterDetails();
    }

    public void WriteChapterDetails()
    {
       if ( includeHighDetails)        
       {
         \\Do something
       }
}

The Details class is a huge class and I don't want to repeat all the methods in the HighDetails class. I want to derive from the Details class and somehow not include the LowDetails. How can I do that?

  • 4
    If your class is so huge that it prevents you from doing the right thing, that is your problem. – Telastyn Jan 28 '15 at 19:00
  • Also, is there really a need for a separate class? From your description, it sounds like HighDetails is little more than a Details class with includeHighDetails set to true and includeLowDetails set to false. – Dan Lyons Jan 28 '15 at 19:02
  • 1
    did you consider using template method pattern? – gnat Jan 28 '15 at 19:03
  • 1
    @gnat I think your comment about the template pattern should be the answer, not just a comment. – Jeff Jan 28 '15 at 19:16
  • 1
    @Jeff there you go – gnat Jan 28 '15 at 19:36
6

This is sort of problems intended to be dealt with using Template method pattern:

...behavioral design pattern that defines the program skeleton of an algorithm in a method, called template method, which defers some steps to subclasses. It lets one redefine certain steps of an algorithm without changing the algorithm's structure...

Applied to your case, it could look like as follows. First, you define algorithm steps that you may need to modify / redefine in subclasses by extracting involved code into separate methods.

That way, WriteChapterDetails becomes a skeleton like mentioned above:

    public void WriteChapterDetails()
    {
       WriteHighDetails();
       WriteLowDetails();
    }

    protected void WriteHighDetails()
    {
       if ( includeHighDetails)        
       {
         //Do something
       }
    }

    protected void WriteLowDetails()
    {
       if (includeLowDetails)
       {
         //Do something
       }
    }

This way opens the code for extension in subclasses.

Next, you define subclass to override desired step of the skeleton:

public class HighDetails : Details
{
    protected override void WriteLowDetails()
    {
       //Do nothing
    }
}

That way, HighDetails inherits everything from Details except for the feature you wanted to do differently (WriteLowDetails).


Side note. This is not directly related to what you asked about, but conditional checks like one for includeHighDetails in your code snippet are code-smell, suggesting that you might be interested to learn about approach of replacing conditional with polymorphism.

I was also somewhat surprised to read your complaint about Details class being huge. Thing is, design sketched in the question seems to be compact and pretty much autonomous. If real code has it mixed in an "omelette" with barely related / unrelated stuff, you better invest some effort in extracting this functionality into a dedicated class.

  • 1
    This is a good and useful pattern when used correctly. Specifically, I recommend only using it for classes where the behavior is expected to be configurable or dynamic due to the changing nature of the algorithm. – user22815 Jan 28 '15 at 19:47
  • @Snowman agree. In my experience it has been rather easy to abuse / overuse. I only jumped in with recommendation at this question because code snippet felt much clear cut for template method – gnat Jan 28 '15 at 20:11
  • looks related: How to enforce how an interface is consumed – gnat Oct 3 '17 at 13:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.