Marinescu devised in [6] a method to translate the informal descriptions of bad
smells [1] and object-oriented design heuristics [7] into applicable so called detection
strategies. The method first decomposes the informal descriptions into parts, which are
then translated into an expression built of metrics and comparisons with thresholds.
These expressions are then composed into one rule with the help of the elementary
logical operators. Marinescu and Lanza elaborate in [5] how developers should sys-
tematically work through the bad smells (here called disharmonies) and step by step
resolve cohesion problems (“identity disharmonies”) then coupling problems (“col-
laboration disharmonies”) and finally problems in the type hierarchy (“classification
disharmonies”). Developers are in general well equipped with this book and established
reengineering und refactoring literature [8], [1], [4].
Overview. The rest of the paper is organized as follows. Section 2 will discuss, how the
same design fragment can be a well respected design pattern and an instance of a well
know bad smell. As the choice of the design pattern is expected to be the result of trade-
offs, the smell detection should be enabled to take the knowledge about the pattern into
account and ignore this smell instance. Section 3 therefore develops our approach based
logic meta programming. We represent the Java code base as Prolog facts, on which we
define detection strategies and design pattern as predicates. Finally we explain, how we
suggest to incorporate the knowledge about pattern into the knowledge about smells.
Section 4 shortly suggests how to use our infrastructure to develop a process of step-
wise evolution of design knowledge. Section 5 finally reports about a case study, that
gives an example where taking developer intentions into account, strongly increases the
precision of a detection strategy.
2 Visitors Tend to have Feature Envy
Objects bring data and behavior together. This is at the core of object-orientation and
allows developers to think of objects in programs similar as of real objects. The devia-
tion from this ideal are the smells data class and feature envy. A class is a data class if
the class has mainly data and only little behavior. A method in a class has feature envy,
if it operates for the major part on data of another class. Still in some situations one
wants to separate the data and the behavior of one conceptual object into two or more
technical objects, which can result in both smells.
The Visitor pattern as in Fig. 1 places functionality that operates on the the data of
certain objects (Elements) in separate classes (Visitors). One reason for this separation
is, that the Elements build a complex object structure and the functionality belongs
rather to the whole structure than to single Elements. Another reason might be, that
the functionality is expected to change more frequently and/or is used only in specific
configurations. Since the functionality in the Visitor accesses the data of the Elements,
this intended collaboration could falsely be identified as Feature Envy.
There are variations of the same data-behavior separation in other design pattern, as
listed in Tab. 1. We separate data into an extra object, if we want other objects to share
this data. So does the ExtrinsicState in the Flyweigth Pattern and the Context in the
Intepreter Pattern. As a result the classes which use this data (Flyweight in Flyweight,
37