Abstraction Smell (2)
Abstraction Smell (2)
SESSION 17 & 18
• Abstraction
• Missing Abstraction
• Imperative Abstraction
• Incomplete Abstraction
• Multifaceted Abstraction
• Unnecessary Abstraction
• Unutilized Abstraction
• Duplicate Abstraction
LEARNING OUTCOMES
Component Description
This smell arises when clumps of data or
Definition encoded strings are used instead of creating a
class or an interface.
• It can expose implementation details to
different abstractions, violating the principle of
encapsulation.
Rationale • When data and associated behavior are spread
across abstractions, it can
lead to tight coupling between entities, resulting
in brittle and non-reusable code.
• Inadequate design analysis
Potential Causes • Lack of refactoring
• Misguided focus on minor performance gain
MISSING ABSTRACTION
Example I
Example I
Example I
• However, in such a case, the logic that processes the numbers will be
spread as well as duplicated in many places.
Example II
Example II
Example II
Example II
Impacted Quality
Impacted Quality
Sometimes, entities are merely data elements and don’t have any
behavior associated with them. In such cases, it may be over-
engineering to represent them as classes or interfaces. Hence, a
designer must carefully examine the application context before
deciding to create an explicit abstraction. For example, check if the
following are needed (a non-exhaustive list) to determine if creating
an abstraction is warranted:
• default initialization of data values using constructors
• validation of the data values
• support for pretty printing the data values
• acquired resources (if any) are to be released
IMPERATIVE ABSTRACTION
Component Description
This smell arises when an operation is turned into
Definition a class. This smell manifests as a class that has
only one method defined within the class.
• The founding principle of object-orientation is to
capture real world objects and rep- resent them
as abstractions. By following the enabling
Rationale
technique map domain entities, objects
recognized in the problem domain need to be
represented in the solution domain, too.
Potential Causes • Procedural Thinking
IMPERATIVE ABSTRACTION
Example
• Each class has exactly one method definition named create, copy,
display, etc., respectively, and suffers from Imperative Abstraction
smell.
• The data items relating to a report such as name of the report, data
elements that need to be displayed in the report, kind of report, etc.
are housed in a “data class” named Report.
IMPERATIVE ABSTRACTION
Example
IMPERATIVE ABSTRACTION
Impacted Quality
Practical Consideration
Component Description
This smell arises when an abstraction does not
support complementary or interrelated methods
Definition completely. For instance, the public interface of
an abstraction may provide an initialize() method
to allocate resources.
• One of the key enabling techniques for
abstraction is to “create coherent and complete
abstractions.” One of the ways in which
Rationale
coherence and completeness of an abstraction
may be affected is when interrelated methods
are not supported by the abstraction.
• Missing Overall Perspective
Potential Causes
• Not Adhering to language or library convention
INCOMPLETE ABSTRACTION
Example
Example
Impacted Quality
Component Description
This smell arises when an abstraction has more
Definition
than one responsibility assigned to it.
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
Rationale
Responsibility Principle says that an abstraction
should have a single well-defined responsibility
and that responsibility should be entirely
encapsulated within that abstraction.
• General purpose abstraction
• Evolution without periodic refactoring
Potential Causes
• The burden of process
• Mixing up concern
MULTIFACETED ABSTRACTION
Example
• Java 8 has introduced new classes supporting date and time (and
other classes such as clocks, duration, etc.) in a package named
java.time so that future clients can use this new package instead.
MULTIFACETED ABSTRACTION
Impacted Quality
Impacted Quality
Component Description
This smell occurs when an abstraction that is
Definition actually not needed (and thus could have been
avoided) gets introduced in a software design.
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
Rationale 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.
• Procedural thinking in object oriented language
• Using inappropriate language features for
Potential Causes
convenient
UNNECESSARY ABSTRACTION
Example
• For the case of the e-commerce application that has two classes;
namely, Best-SellerBook and Book, there are many possible
refactoring solutions.
Impacted Quality
• For example, in case of the Object Adapter pattern, the Adapter class
may appear to merely delegate client requests to the appropriate
method on the Adaptee. However, the primary intention behind the
Adapter class is to fulfill the specific, well-defined responsibility of
adapting the Adaptee’s interface to the client needs.
• The JavaDoc for StrictMath notes: “By default many of the Math
methods simply call the equivalent method in StrictMath for their
implementation.”
• Here, note that Math is less portable but can result in better
performance when compared to StrictMath.
Component Description
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
Definition
not being used by anyone. Orphan abstractions—Stand-alone
interfaces/abstract classes that do not have any derived
abstractions
One of the enabling techniques for applying the principle of
abstraction is to assign a single and meaningful responsibility to
Rationale 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.
• Speculative Design
Potential
• Changing Requirement
Causes
• Leftover garbage
UNUTILIZED ABSTRACTION
Example
Example
• All the uses of the sun.misc.Service class can be replaced by the use
of java.util. ServiceLoader class.
Component Description
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
Definition
whether they share similar behavior. Identical implementation
—This is when two or more abstractions have semantically
identical member definitions
Avoid duplication is an important enabling technique for the
effective application of the principle of abstraction. If two or more
abstractions have an identical name, it affects understandability
Rationale
of the design. Developers of client code will be confused and
unclear about the choice of the abstraction that should be used
by their code.
• Copy paste programming
Potential
• Ad hoc maintenance
Causes
• Lack of communication
DUPLICATE ABSTRACTION
Example
Impacted Quality
• Since Bounded Context is one of the patterns that help deal with the
larger problem of modeling large domains, such types with same
names in different contexts is acceptable.
DUPLICATE ABSTRACTION
• For example, the code for methods such as binarySearch, sort, etc.
are duplicated seven times in the java.util.Arrays class because it is
not possible to write a single generic method that takes different
primitive type arrays.