Binus University Code Reengineering Abstraction Smell
Binus University Code Reengineering Abstraction Smell
Year : 2017
Abstraction Smell
Session 15 & 16
Learning Outcomes
- Missing Abstraction
- Imperative Abstraction
- Incomplete Abstraction
- Multifaceted Abstraction
- Unnecessary Abstraction
- Unutillized Abstraction
- Duplicate Abstraction
Abstraction is a powerful principle that provides a means for effective yet simple
communication and problem solving. Company logos and traffic signs are
examples of abstractions for communication. Mathematical symbols and
programming languages are examples of abstraction as a tool for problem
solving.
Abstraction Key Enabling
Technique
Abstraction Key Enabling
Technique
Component Description
Definition This smell arises when clumps of data or encoded
strings are used instead of creating a class or an
interface.
Rationale • It can expose implementation details to
different abstractions, violating the principle of
encapsulation.
• When data and associated behavior are spread
across abstractions, it can
lead to tight coupling between entities,
resulting in brittle and non-reusable code.
Potential Causes • Inadequate design analysis
• Lack of refactoring
• Misguided focus on minor performance gain
Missing Abstraction Example I
The example discussed the need to handle different kinds of ISBN numbers
such as ISBN-10 and ISBN-13. A potential refactoring would be to abstract
ISBN as an abstract class or interface with common operations in it. ISBN-10
and ISBN-13 can be subclasses that extend the ISBN supertype
Missing Abstraction Example II Suggested
Refactoring
Client programs that needed programmatic access to the stack trace elements
had to write code to process the stack trace to get, for example, the line
numbers or find if the bug is a duplicate of another already-filed bug. Due to
this dependence of client programs on the format of the string, the designers of
JDK were forced to retain the string encoding format in future versions of
JDK.
Missing Abstraction Example III Suggested
Refactoring
The Java API was improved in version 1.4 to have programmatic access to the
stack trace through the introduction of StackTraceElement class. Note that
even though a new method is added, the method printStackTrace() and the
format of the stack trace has been retained to support the existing clients.
Component Description
Definition This smell arises when an operation is turned into
a class. This smell manifests as a class that has only
one method defined within the class.
Rationale The founding principle of object-orientation is to
capture real world objects and rep- resent them as
abstractions. By following the enabling technique
map domain entities, objects recognized in the
problem domain need to be represented in the
solution domain, too.
Component Description
Definition This smell arises when an abstraction does not
support complementary or interrelated methods
completely. For instance, the public interface of an
abstraction may provide an initialize() method to
allocate resources.
Rationale One of the key enabling techniques for abstraction
is to “create coherent and complete abstractions.”
One of the ways in which coherence and
completeness of an abstraction may be affected is
when interrelated methods are not supported by
the abstraction.
Potential Causes • Missing Overall Perspective
• Not Adhering to language or library convention
Incomplete Abstraction Example
Component Description
Definition This smell arises when an abstraction has more
than one responsibility assigned to it.
Rationale An important enabling technique to effectively
apply the principle of abstraction is to assign single
and meaningful responsibility for each abstraction.
In particular, the Single Responsibility Principle
says that an abstraction should have a single well-
defined responsibility and that responsibility
should be entirely encapsulated within that
abstraction.
Potential Causes • General purpose abstraction
• Evolution without periodic refactoring
• The burden of process
• Mixing up concern
Multifaceted Abstraction Example
None
Unnecessary Abstraction
Component Description
Definition This smell occurs when an abstraction that is actually not
needed (and thus could have been avoided) gets introduced in
a software design.
Rationale A key enabling technique to apply the principle of abstraction
is to assign single and meaningful responsibility to entities.
However, when abstractions are created unnecessarily or for
mere convenience, they have trivial or no responsibility
assigned to them, and hence violate the principle of
abstraction. Since the abstraction is needlessly introduced in
the design, this smell is named Unnecessary Abstraction.
Potential Causes • Procedural thinking in object oriented language
• Using inappropriate language features for convenient
• Over Engineering
Unnecessary Abstraction Example
Consider the case of an e-commerce application that has two classes: namely, Best-
SellerBook and Book. Whenever the client wants to create a best-seller book, it
creates an instance of a BestSellerBook. Internally, BestSellerBook delegates all
the method calls to the Book class and does nothing else. Clearly, the BestSeller-
Book abstraction is unnecessary since its behavior is exactly the same as the Book
abstraction.
Unnecessary Abstraction Example Suggested
Refactoring
For the case of the e-commerce application that has two classes; namely,
Best-SellerBook and Book, there are many possible refactoring solutions. One
solution, for instance, is to remove the BestSellerBook class and instead add
an attribute named isBestSeller (along with a getter and a setter) in the Book
class. Now, when the client code wants to indicate if a book is a bestseller,
it will set the attribute isBestSeller instead of creating an instance of the
erstwhile BestSellerBook class.
Impacted Quality
Accommodating variations
Unutilized Abstraction
Component Description
Definition This smell arises when an abstraction is left unused (either not
directly used or not
reachable). This smell manifests in two forms:
Unreferenced abstractions—Concrete classes that are not
being used by anyone
Orphan abstractions—Stand-alone interfaces/abstract classes
that do not have any derived abstractions
Rationale One of the enabling techniques for applying the principle of
abstraction is to assign a single and meaningful responsibility
to an entity. When an abstraction is left unused in design, it
does not serve a meaningful purpose in design, and hence
violates the principle of abstraction.
Potential Causes • Speculative Design
• Changing Requirement
• Leftover garbage
• Fear of breaking code
Unnecessary Abstraction Example
Class libraries and frameworks usually provide extension points in the form of
abstract classes or interfaces. They may appear to be unused within the library or
framework. However, since they are extension points that are intended to be
used by clients, they cannot be considered as Unutilized Abstractions.
Duplicate Abstraction
Component Description
Definition This smell arises when:
Identical name—This is when the names of two or more
abstractions are identical. While two abstractions can
accidentally have the same name, it needs to be analyzed
whether they share similar behavior.
Identical implementation—This is when two or more
abstractions have semantically identical member definitions
Classes java.util.Date and its derived class java.sql.Date share the same
name. The compiler does not complain that the base and derived classes
have the same name because these classes belong to different packages.
However, it is very confusing for the users of these classes. For example,
when both these classes are imported in a program, it will result in a
name ambiguity that must be resolved manually by explicitly qualifying
the class names.
Duplicate Abstraction Example Suggested
Refactoring
Accommodating variations
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.