CSC/ECE 517 Fall 2010/ch7 7f LG: Difference between revisions
No edit summary |
|||
Line 3: | Line 3: | ||
Having to call super when inheriting from a super-class is considered an anti-pattern or code smell. Whenever you have to remember to do something besides inheriting the method every time, chances are that you will forget it and this is a sign of a bad API. We can solve this by defining a public method that does the housekeeping and calls a second method, often called the hook, which the subclass has to override. Following this refactor will strengthen the API by alleviating the programmer from remembering to call super each time. | Having to call super when inheriting from a super-class is considered an anti-pattern or code smell. Whenever you have to remember to do something besides inheriting the method every time, chances are that you will forget it and this is a sign of a bad API. We can solve this by defining a public method that does the housekeeping and calls a second method, often called the hook, which the subclass has to override. Following this refactor will strengthen the API by alleviating the programmer from remembering to call super each time. | ||
==Example== | ==Example== | ||
The following example is inspired in both the Wikipedia and Martin Fowler’s examples. By design, each subclass of vehicle should call super when overriding MoveForward and then perform their specific behavior. The programmer must remember to do so, if he does not, the vehicle will not move. | The following example is inspired in both the Wikipedia [[#References|[1]]] and Martin Fowler’s [[#References|[2]]] examples. By design, each subclass of vehicle should call super when overriding MoveForward and then perform their specific behavior. The programmer must remember to do so, if he does not, the vehicle will not move. | ||
<pre> | <pre> | ||
public class Vehicle { | public class Vehicle { | ||
Line 24: | Line 24: | ||
} | } | ||
</pre> | </pre> | ||
Following the solution proposed in Martin Fowler’s article, we refactor this code adding a hook called AfterMoveForward, which is the method the subclasses must override. Whenever we call MoveForward within a Car object, the appropriate movement and car-specific action will be performed. | Following the solution proposed in Martin Fowler’s article [[#References|[2]]], we refactor this code adding a hook called AfterMoveForward, which is the method the subclasses must override. Whenever we call MoveForward within a Car object, the appropriate movement and car-specific action will be performed. | ||
<pre> | <pre> | ||
public class Vehicle { | public class Vehicle { | ||
Line 46: | Line 46: | ||
} | } | ||
</pre> | </pre> | ||
==References== | |||
[[#References|[1]]] Wikipedia. (2010, December) Wikipedia - Call super. [Online]. http://en.wikipedia.org/wiki/Call_super | |||
[[#References|[2]]] Martin Fowler. (2010, December) Martin Fowler. [Online]. http://martinfowler.com/bliki/CallSuper.html |
Revision as of 22:57, 1 December 2010
Call “super” Anti-Pattern
Introduction
Having to call super when inheriting from a super-class is considered an anti-pattern or code smell. Whenever you have to remember to do something besides inheriting the method every time, chances are that you will forget it and this is a sign of a bad API. We can solve this by defining a public method that does the housekeeping and calls a second method, often called the hook, which the subclass has to override. Following this refactor will strengthen the API by alleviating the programmer from remembering to call super each time.
Example
The following example is inspired in both the Wikipedia [1] and Martin Fowler’s [2] examples. By design, each subclass of vehicle should call super when overriding MoveForward and then perform their specific behavior. The programmer must remember to do so, if he does not, the vehicle will not move.
public class Vehicle { ... public void MoveForward() { // Housekeeping ValidateMove(); UpdateDisplay(POSITION); ... } ... } public class Car : Vehicle { ... public void MoveForward() { base.MoveForward(); UpdateDisplay(WHEEL_MARKS); // Do Car-specific actions } ... }
Following the solution proposed in Martin Fowler’s article [2], we refactor this code adding a hook called AfterMoveForward, which is the method the subclasses must override. Whenever we call MoveForward within a Car object, the appropriate movement and car-specific action will be performed.
public class Vehicle { ... public void MoveForward() { // Housekeeping ValidateMove(); UpdateDisplay(POSITION); ... AfterMoveForward(); } protected abstract void AfterMoveForward(); ... } public class Car : Vehicle { ... public void AfterMoveForward() { UpdateDisplay(WHEEL_MARKS); // Do Car-specific actions } ... }
References
[1] Wikipedia. (2010, December) Wikipedia - Call super. [Online]. http://en.wikipedia.org/wiki/Call_super
[2] Martin Fowler. (2010, December) Martin Fowler. [Online]. http://martinfowler.com/bliki/CallSuper.html