Refactoring Day 8 : Replace Inheritance with Delegation


All too often inheritance is used in the wrong scenarios. Inheritance should only be used in logical circumstances but it is often used for convenience purposes. I’ve seen this many times and it leads to complex inheritance hierarchies that don’t make sense. Take the following code:

   1: public class Sanitation
<pre><span class="lnum">   2:</span> {</pre>

<pre><span class="lnum">   3:</span>     <span class="kwrd">public</span> <span class="kwrd">string</span> WashHands()</pre>

<pre><span class="lnum">   4:</span>     {</pre>

<pre><span class="lnum">   5:</span>         <span class="kwrd">return</span> <span class="str">"Cleaned!"</span>;</pre>

<pre><span class="lnum">   6:</span>     }</pre>

<pre><span class="lnum">   7:</span> }</pre>

<pre><span class="lnum">   8:</span>&nbsp; </pre>

<pre><span class="lnum">   9:</span> <span class="kwrd">public</span> <span class="kwrd">class</span> Child : Sanitation</pre>

<pre><span class="lnum">  10:</span> {</pre>

<pre><span class="lnum">  11:</span> }</pre>

In this instance, a Child is not a “Sanitation” and therefore doesn’t make sense as an inheritance hierarchy. We can refactor by initializing an instance of Sanitation in the Child constructor and delegating the call to the class rather than via inheritance. If you were using Dependency Injection, you would pass in the Sanitation instance via the constructor, although then you would need to register your model in your IoC container which is a smell IMO, you get the idea though. Inheritance should ONLY be used for scenarios where inheritance is warranted. Not instances where it makes it quicker to throw down code.

   1: public class Sanitation
<pre><span class="lnum">   2:</span> {</pre>

<pre><span class="lnum">   3:</span>     <span class="kwrd">public</span> <span class="kwrd">string</span> WashHands()</pre>

<pre><span class="lnum">   4:</span>     {</pre>

<pre><span class="lnum">   5:</span>         <span class="kwrd">return</span> <span class="str">"Cleaned!"</span>;</pre>

<pre><span class="lnum">   6:</span>     }</pre>

<pre><span class="lnum">   7:</span> }</pre>

<pre><span class="lnum">   8:</span>&nbsp; </pre>

<pre><span class="lnum">   9:</span> <span class="kwrd">public</span> <span class="kwrd">class</span> Child</pre>

<pre><span class="lnum">  10:</span> {</pre>

<pre><span class="lnum">  11:</span>     <span class="kwrd">private</span> Sanitation Sanitation { get; set; }</pre>

<pre><span class="lnum">  12:</span>&nbsp; </pre>

<pre><span class="lnum">  13:</span>     <span class="kwrd">public</span> Child()</pre>

<pre><span class="lnum">  14:</span>     {</pre>

<pre><span class="lnum">  15:</span>         Sanitation = <span class="kwrd">new</span> Sanitation();</pre>

<pre><span class="lnum">  16:</span>     }</pre>

<pre><span class="lnum">  17:</span>&nbsp; </pre>

<pre><span class="lnum">  18:</span>     <span class="kwrd">public</span> <span class="kwrd">string</span> WashHands()</pre>

<pre><span class="lnum">  19:</span>     {</pre>

<pre><span class="lnum">  20:</span>         <span class="kwrd">return</span> Sanitation.WashHands();</pre>

<pre><span class="lnum">  21:</span>     }</pre>

<pre><span class="lnum">  22:</span> }</pre>

This refactoring comes from Martin Fowlers Refactoring book. You can view the original refactoring here

This is part of the 31 Days of Refactoring series. For a full list of Refactorings please see the original introductory post.

← Refactoring Day 7 : Rename (method, class, parameter)
Refactoring Day 9 : Extract Interface →