5

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?

gnat
  • 21,213
  • 29
  • 113
  • 291
Tarveen
  • 71

1 Answers1

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.

gnat
  • 21,213
  • 29
  • 113
  • 291
  • 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. –  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