Professional Documents
Culture Documents
Binus University Code Reengineering Hierarchy Smell
Binus University Code Reengineering Hierarchy Smell
Year : 2017
Hierarchy Smell
Session 21 & 22
Learning Outcomes
- Missing Hierarchy
- Unnecessary Hierarchy
- Unfactored Hierarchy
- Wide Hierarchy
- Speculative Hierarchy
- Deep Hierarchy
- Rebellious Hierarchy
- Broken Hierarchy
- Multipath Hierarchy
- Cyclic Hierarchy
Ensure substitutability. Ensure that the types in the hierarchy follow the
Liskov’s Substitution Principle (LSP); in other words, a reference of a supertype
can be substituted with objects of its subtypes without altering the behavior of the
program.
The chained if-else code block has explicit type checks for AbstractButton, JToolBar, and
JTextComponent. The code where the getMargin() method is called is the same within all
the conditions. As one can observe from the inline comments, the concerned
developer consciously chose a hack, and in that process introduced this smell in
design. Note that the explicit type checks as shown above is repeated in two other
places in the same source file.
Missing Hierarchy Example
Refactoring
•Reliability—This smell can impact reliability in many ways. Some of the ways
are:
• A common problem when using type-based checking is that a developer
may miss out on some of the checks for type codes.
Practical Consideration (Reification)
File formats usually “mark” the data content within the file to indicate the type of
the data (for instance, the file format for .class in Java). This encoding helps read
data from the flat-file: the program needs to first check the type information of
the data and then process the data.
Unnecessary Hierarchy
Component Description
Definition This smell arises when the whole inheritance hierarchy is
unnecessary, indicating that inheritance has been applied
needlessly for the particular design context.
Rationale For effective application of the principle of hierarchy, it is
important to adhere to the enabling technique “apply
meaningful classification.” For a “meaningful” application of
classification, the focus should be more on capturing the
commonalities and variation in behavior rather than data.
Potential Causes • Subclasses instead instantiating
• Taxonomy Mania
Missing Hierarchy Example
Consider the case of a text editor that supports multiple fonts. In this application,
when the user selects the font, the editor just passes this information to the
underlying OS which renders the text in the selected font. Figure shows how
inheritance can be used to support multiple fonts in such an editor - Font is the
supertype and fonts such as Arial and Calibri are supported via Font’ s subtypes
named ArialFont and CalibriFont. However, if we were to reflect on this design, we will
realize that since the editor does not change its behavior based on the font,
classifying the types of fonts within a hierarchy is unnecessary. Hence, this design
suffers from Unnecessary Hierarchy smell.
Missing Hierarchy Example
Refactoring
In the case of Font hierarchy, the suggested refactoring solution is to make the
subtypes of Font into objects of Font, such as Arial and Calibri objects. But note that
another possible refactoring is to model this list of fonts as an enumeration
(Figure 6.11). Choosing the correct refactoring option would depend on the
context.
Impacted Quality
Understandability—If a hierarchy is created unnecessarily, it complicates the
design. Hence, this smell impacts understandability of the design.
None
Unfactored Hierarchy
Component Description
Definition Duplication in sibling types: Sibling types in the hierarchy have
similar code segments that can be moved into one of their
supertypes.
Duplication in super and subtypes: There are similar code
segments in super and subtypes indicating redundant code in
the subtypes.
Rationale If the common interface across types is elevated in the
hierarchy, clients can depend on this common interface rather
than the concrete implementation aspects of the subtypes.
If duplicated implementation across types in the hierarchy is
removed by elevating the implementation to a supertype,
unnecessary duplication across the types is avoided.
Potential Causes • Copying subtype
• Improve handling of outlier
Unfactored Hierarchy Example
The abstract class java.text.NumberFormat in JDK 7 provides support for for-
matting and parsing numbers in any locale. It has two subclasses: ChoiceFormat
and DecimalFormat. With ChoiceFormat, we can attach a format to a range of
numbers and with DecimalFormat, we can format decimal numbers for any
locale
In the case of NumberFormat example, the signature of two methods is the same in
the subclasses and their implementations are different. Hence, a suggested
refactoring is to introduce abstract methods applyPattern() and toPattern() in the
supertype NumberFormat
Impacted Quality
Understandability—Duplication within the hierarchy unnecessarily bloats the
code and increases the cognitive load on developers.
Changeability and Reliability—A change to the code that is common across a set
of types needs to be replicated across all those types, failing which a defect may
occur.
Component Description
Definition This smell arises when an inheritance hierarchy is “too” wide
indicating that intermediate types may be missing.
Rationale • Missing intermediate types may force the clients of that
hierarchy to directly refer to the subtypes. This dependency
affects the changeability and extensibility of the hierarchy.
• There may be unnecessary duplication within types (since
commonality cannot be properly abstracted due to lack of
intermediate types).
Potential Causes • Ignoring generalization
• Lack of refactoring
Wide Hierarchy Example
Component Description
Definition This smell arises when one or more types in a hierarchy are
provided speculatively (i.e., based on imagined needs rather
than real requirements).
Rationale One of the key enabling techniques for the effective application
of the principle of hierarchy is “apply meaningful
generalization.” Generalization should be performed for
exploiting commonalities in existing types
Potential Causes • Future-proofing
• Over-engineering
Wide Hierarchy Example
Testability—It may require more effort to test unnecessary generic types in the
hierarchy when compared to testing a hierarchy without speculative types. This
impacts the testability of the overall design.
Practical Consideration (Reification)
None
References
Girish Suryanarayana, Ganesh Samarthyam and Tushar Sharma, Chapter 2 - Design Smells, In
Refactoring for Software Design Smells, edited by Girish Suryanarayana and Ganesh
SamarthyamTushar Sharma, Morgan Kaufmann, Boston, 2015, Pages 9-19, ISBN
9780128013977, http://dx.doi.org/10.1016/B978-0-12-801397-7.00002-3.
M. Fowler and K. Beck, "Bad Smells in Code," in Refactoring: Improving the Design of
Existing Code, Addison-Wesley, 2000
W. Stevens, G. Myers and L. Constantine, "Structured Design," IBM Syst J, vol. 13, no. 2, pp.
115-139, 1974.