Design Patterns During Software Reengineering Less
Design Patterns During Software Reengineering Less
Peter Wendorff
ASSET GmbH, 46147 Oberhausen, Germany
ASSET-GmbH 0t-online.de
77
$10.000 2001 IEEE
0-7695-1028-0/01
address the problem. In [ 111 the authors report the results merely one design option among others during software
of a controlled experiment. Their valuable empirical development. The decision to favour one of these options
research investigates the effects of design patterns on over the others should normally be based on the detailed
software maintenance effort, but they do not discuss and specific quality goals of the software project.
procedures to deal with inappropriate patterns. Therefore the choice in favour or against the use of a
In section 2 we discuss some theoretical issues related pattern must be based on the quality goals of the project.
to patterns. In section 3 we present typical problems that
can be introduced into source code by the unreflective use 2.4. Flexibility
of patterns. In section 4 we will present a sequence of
simple steps for the assessment of patterns from a One key concern of patterns is flexibility. In [7] Gamma
reengineering perspective. et al. note: "A design that doesn't take change into
account risks major redesign in the future. Those changes
2. Aspects-of Patterns might involve class redefinition and reimplementation,
client modification, and retesting. Redesign affects many
In this section we will discuss some aspects of patterns parts of the software system, and unanticipated changes
that *e relevant in the context of this paper, but are invariably expensive. Design patterns help you avoid
naturally we cannot provide a comprehensive treatment this by ensuring that a system can change in specific
of the subject. ways". The crucial point to notice here is that a pattern
will usually add to a particular aspect of flexibility, but it
2.1. Basic Elements cannot provide universal flexibility. If a pattern is applied
to enhance flexibility of a software design, careful judge-
In [7] the following definition is given: "The design ment is required to ensure that the pattern promotes the
patterns in this book are descriptions of communicating desired aspect of flexibility.
objects and classes that are customized to solve a general
design problem in a particular context". The essential 2.5. cost
elements of a pattern are [71:
- the "pattern name" as denotation of the concept Gamma et al. note that the flexibility introduced by
- the "problem" as description of the class of situations patterns comes at a price when they discuss the
when the concept is applicable mechanism of delegation that is used by many patterns:
- the "solution" which gives an abstract description of a "Delegation has a disadvantage it shares with other
generic system of elements and their relationships that techniques that make software more flexible through
solves the problem object composition: Dynamic, highly parameterized
- the "consequences" that result from the application of software is harder to understand than more static
the solution, for example trade-offs, costs, and benefits software. There are also run-time inefficiencies, but the
human inefficiencies are more important in the long
2.2. Critical Success Factors run".
Patterns usually lead to an increased number of
There exist a lot of critical success factors (CSFs) for the software artefacts (e.g. classes, files, associations, etc.),
application of a pattern, and empirical research shows which normally increase the static complexity of a
that these factors are barely understood at the present software system considerably. Furthermore, when the
state of the art [ll]. Some CSFs are discussed in books additional associations are instantiated at run-time, they
like [3] or [7] in an informal way, leaving much space for result in additional and often volatile links between
personal opinion. Therefore the decision to apply a objects, and this usually increases the dynamic
pattern in a particular situation is to a large degree a complexity of a software system significantly.
matter of subjective judgement. Popular collections of
patterns like [9], which are frequently consulted by pro- 2.6. Cost of Change
grammers, do barely discuss critical success factors at all.
Recently "Extreme Programming (XP)" has been
2.3. Design Options proposed as a new "lightweight" software engineering
methodology [2], and it is immensely popular among
A pattern is not necessarily a best practice, it is rather a practitioners. X P is based on four values, one of which is
proven practitioner's approach. Therefore a pattern is "simplicity". This idea is explained in [2]: "XP is making
78
a bet. It is betting that it is better to do a simple thing can often be narrowed down. If uncertainty decreases,
today and pay a little more tomorrow to change it if it then the need for flexibility may decrease accordingly.
needs it, than to do a more complicated thing today that Therefore it is conceivable that a pattern that is intro-
may never be used anyway". duced into a design at an early stage of the software
We will not give our position on X P here, we rather development process may become obsolete at a later
note that X P is a methodology that has emerged in stage.
practice and represents lessons learned by large numbers
of experienced software engineers. Clearly there is a case 2.9. Removal
for simplicity from an ecomomic point of view. As the
application of patterns frequently leads to more complex In the case of the removal of a pattern from code we have
software, there may be reasons to caution their use. to balance three conflicting issues (cf. [12]): First the
possible benefit of the pattern. Second the possible extra
2.7. Software Quality cost of the pattern. Third the cost of its removal.
The term "software quality" already denotes an elusive 2.10. Empirical Research
and multidimensional concept [8]. None of the leading
textbooks [3], [7], or [9] on patterns refers to any explicit The patterns movement was not theory-driven at its
model of software quality, but their authors frequently inception, and it still is not at the time of writing, it is
mention software quality attributes like "flexibility", rather an eclectic practitioner's approach. This is
"comprehensibility", "maintainability", etc. without reflected by the lack of empirical research into patterns.
giving clear operational definitions for these concepts. The severe lack of theoretical groundwork makes it
It is a typical situation that different software quality difficult to assess the cost/benefit ratio of patterns
attributes are in a conflicting relationship to another [8]. objectively. In [ l l ] the authors elaborate the blurred
For example it is possible that the application of a pattern operational definitions of software quality concepts
results in code that is more flexible, but that is more claimed in favour of patterns. Their work shows that
complex as well. Whether the overall economic effect of contrary to common belief the beneficial effects of
a pattern is positive or negative in such a case is therefore patterns are not universally obvious. Therefore it must be
dependent on future needs that are not fully anticipated at concluded that at the present state of affairs there is a
the time of design and coding. It would be a break- serious lack of hard scientific evidence for the usefulness
through in software engineering, if we could predict of patterns in many situations.
software quality attributes in a comprehensive and objec-
tive way. Sadly we are far from that situation [IO]. 3. Inadequate Application of Patterns
Therefore the decision in favour or against the use of
a pattern is to some degree a matter of subjective In this section we will give some examples from our
judgement for at least two reasons. First, our ability to reengineering work where the application of patterns has
measure the effects that patterns have on software quality been questionable. This is not intended to criticise these
are very limited [IO]. Second, there is no firm and formal widely accepted patterns. Instead we want to illustrate
theory that links patterns to software quality concepts, how and why patterns were in some cases improperly
and therefore we do not have an explicit model of how applied by software engineers.
patterns work, what their critical success factors are, how
these factors interact, etc. [ 111. 3.1. The Proxy Pattern
2.8. Software Lifecycle The "proxy" pattern as described in [3], [7], and [9] is a
simple one with an easy to grasp rationale behind it. Its
Any planning situation that has to deal with a dynamic simplicity makes it a typical "beginner's pattern", and
environment must care about uncertainty. A constructive according to our experience, beginners tend to use it
way to deal with this uncertainty is to build flexibility freely.
into a product, so that it can be modified easily. Patterns The basic idea behind the proxy pattern is to use a
provide a way to build flexibility into a software product. placeholder (called the "proxy") for another object (called
In the course of a software development project the the "real subject") in order to control access to the real
degree of uncertainty often decreases considerably. For subject [7]. The proxy constitutes an additional layer of
example as experience in the application domain indirection and manages the requests made by clients to
increases, the number of relevant environmental factors
79
the real subject. The proxy and its real subject exhibit the The removal of a proxy pattern in presence of com-
same interface, and therefore the proxy can be substituted plex pre-processing or post-processing, proved to be very
wherever its corresponding real subject is expected by difficult and needed careful attention to side effects.
clients. A typical application of the proxy pattern are In one subsystem with about 3000 lines of code we
expensive operations, where the proxy decides when and removed 3 out of 7 proxy patterns altogether, leading PO a
how to forward the requests to the real subject, in order to reduction of 200 lines of code.
ensure efficient processing.
During our reengineering analysis the value of many 3.2. The Observer Pattern
proxies found in the code seemed to be doubtful. We
noticed the following problems: The observer pattern as described in [3], [7], and [9] is a
- In many cases developers justified the application of well-known pattern with a long history. Originally it
the proxy pattern with expected future needs for emerged as part of the Smalltalk environment where it
flexibility, access control, and performance. In fact in had been developed to facilitate GUI design, and where it
most cases these future needs never materialised. In is known as model-view-controller (MVC) pattern. Since
these cases the proxy pattern often remained in the those early days the concept has been refined and genera-
code, the rationale behind its use disappeared. lised, and it has been applied to other domains as well.
- The Proxy pattern naturally leads to a substantial The original MVC approach divides an interactive
increase in the number of classes (and usually files). graphical application into two fundamental parts: an
For example the simple variant of the proxy patterns abstract application (the "model") and a user interface
described in 171 necessitates one interface class and two (the "views" and the "controllers") that handle all YO
concrete classes, compared to a single class for a functions. The MVC defines a generic protocol for the
simple solution. This means that the size and com- communication of these three kinds of parts. There are
plexity of the software increases considerably. two important aspects of the MVC approach. First, it is
- In [3] it is proposed to include some kind of pre- particularly suited in the case of a one-to-many depen-
processing and post-processing for a request to a class dency between a model and several views [7]. Second it
in the proxy class of that class. Surely this division of facilitates reuse of software through the generic protocol
responsibilities between classes makes sense in some and the clear division of labour between the participating
special cases, but it can make the interaction between objects.
objects pretty complicated. We found a case where In our project a framework for GUI implementation
considerable and complicated functionality was scat- (an industry standard) was used that provides a
tered over a hierarchy of proxy classes without a comprehensive and reasonable support infrastructure for
documented or conceivable rationale. modal dialogues. To our utter surprise one programmer
- The proxy pattern introduces an additional level of had not used this proven and free architecture but rather
indirection which impedes comprehension of the implemented a complex MVC model on his own. From
dynamic flow of control at run-time because it bloats an economic point of view this was clearly an extremely
the call stack. This can make debugging much harder. bad solution for three reasons. First, by its very nature a
During our reengineering analysis we put every proxy modal dialogue does not have multiple views. Second, in
pattern used in the code to the test and removed a large our project it was never considered to reuse the dialogues
number of proxies completely. in any way. Third, the modal dialogues in question were
In many cases the proxy objects did simply forward rather primitive and did simply not necessitate the sepa-
requests to their real subjects directly without adding any ration of concerns promoted by the MVC model.
processing. As is correctly noted in [9] these proxies in A post mortem analysis of the decision process that
their "pure form" are not useful. Fortunately their remo- led to the uneconomical decision in favour of the MVC
val is straightforward, because one can simply substitute approach revealed that the programmer in question
the real subject for the proxy. This still is cumbersome - wanted to gain experience with the MVC approach
and monotone work, but the economies of classes and - justified his design decision in terms of "flexibility"
files are usually substantial. Furthermore this work can and "reusability"
be done in a mechanical fashion and does not involve the - found it simple to convince the young and inexpe-
risk of introducing errors into the code. rienced project leader by referring to the purported
The removal of a proxy pattern from the code was superiority of patterns over all other solutions
straightforward in cases where there was a clear sepa- An important aspect in this case is the use of the
ration of responsibilities between the proxy class and the buzzwords "flexibility" and "reusability". These two
other classes involved in the pattern. buzzwords are ascribed to certain patterns in most of the
80
literature on patterns (cf. [31, [7], and [9]). Clearly these solution. In many cases the bridge pattern was chosen in
two quality attributes generally do not harm, but in this a rather mechanical fashion.
case they were not required and they were achieved at an Later many of the premeditated change requests did
irresponsible cost. not materialise, and in these cases the bridge pattern
From an economic point of view it would have been usually stayed in place even though the rationale behind
desirable to remove the MVC approach from the code. If its use had disappeared completely.
the aforementioned industry standard had been used, that It is noteworthy that in several cases the original
would have resulted in a fraction of the code size that rationale behind the choice of the bridge pattern could
was effected by the MVC approach. not be established at all, due to a lack of appropriate
Unfortunately the removal of the MVC architecture documentation. This does compromise the idea of flexi-
would have amounted to a completely new design and bility supported by patterns. It is usually helpful to know
implementation of the graphical user interface and was the kind of flexibility that is provided by a pattern in a
therefore out of the question. particular context, in order to exploit this inherent flexi-
bility efficiently. If the corresponding documentation is
3.3. The Bridge Pattern not present, then relevant options provided by the pattern
may go unnoticed.
The bridge pattern [7], [9] provides a way to decouple an During our reengineering work we only addressed the
abstraction and its implementation. There is a number of degenerate form of the bridge pattern. Removing such a
potential situations when full independence between bridge pattern from code is usually a straightforward
abstractions and their implementations makes sense, but merger of two classes into one class. In one subsystem we
these situations are rather special in nature. removed 2 out of 3 bridge patterns with an economy of
Generally abstraction is not a value in itself, instead it 190 out of 1400 lines of code.
is a means to support human understanding and commu-
nication. Therefore a software design should exhibit a 3.4. The Command Pattern
useful degree of abstraction, ideally that one with the best
cosdbenefit ratio in a given situation. The command pattern [7], [9] (cf. the more elaborate
Many programming languages provide language pattern “command processor” in [3]) is based on the
features that allow a certain degree of independence representation of commands by objects. Thereby complex
between an abstraction and its implementation. For command structures can be represented by a flexible
example in our project C++ has been used, and this object model. This approach can be used to design
language makes a distinction between a class declaration applications that are easily extensible.
and its corresponding implementation, and the two are In our project the requirement was that about 100
usually placed in separate files. We think that one should elementary operations had to be performed in a number
first carefully evaluate the abstraction mechanisms of well-defined sequences on a set of data. The original
directly supported by the implementation language. Only requirement was that the sequences should be read from
if there is evidence that these abstraction mechanisms are a database. Therefore the designers decided to use the
not sufficient in the given context, then more compli- command pattern, which was a reasonable choice at that
cated and indirect abstraction mechanisms should be time.
considered. Our post mortem examination of the ensuing design
The case where there is only one implementation for process told an interesting story. After the decision in
an abstract concept is mentioned as “a degenerate case of favour of the command pattern the designers got inspired
the Bridge patJern” in [7], and the authors note that this by the additional options associated with that pattern. A
pattern has Gery limited applicability. We found degen- number of additional functions were added .to the design
erate bridge patterns several times during our reengin- that had never been mentioned in the requirements of the
eering work. Seemingly some of the programmers in the project. As a matter of fact these functions were added
project were beset by the idea of separating an abstraction because they were noted in the popular text [7] as
and its single corresponding implementation. possible options, although they were not part of the
The post mortem examination of the design decisions requirements specification.
in favour of the bridge pattern revealed a recurring Then the requirements changed. The idea to read the
course of events: During the early design stages the sequences of operations from a database was dropped. At
designers frequently overestimated the need for later that stage the command pattern achitecture had deve-
extensions of the software. Faced with uncertain future loped into a very complex software artefact with loads of
requirements they usually opted for the more flexible unnecessary and complicated features that was intricately
81
intertwined with other parts of the software achitecture. patterns documented as "proxy" patterns, which accor-
Even the original designers themselves freely admitted ding to [7] are "adaptor" patterns.
that their solution was completely over the top. To Step 3: Reconstructing the original motivation
In this situation a full reengineering of the failed behind the application of a pattern is an interesting, yet
command pattern architecture would have been desirable, difficult activity. In our project much of the design
but because of its complexity that was no longer a viable documents originated in the mid 90s and were badly
option. maintained or even outdated. At one stage one of the
Clearly it would be unfair to blame patterns for the major software designers, who had left the project in the
ill-judgement of individual software engineers. Never- meantime, was hired for one day to discuss these issues.
theless our investigations indicated that the cookbook On the backcloth of the project's history this designer
style of much of the patterns literature might- have confirmed a number of our conjectures concerning
stimulated the playfulness of some software engineers in inappropriately applied patterns.
the case of our project. During our post mortem analysis into the inappro-
priate use of patterns two general categories became
4. Removal of Patterns apparent. In the first category are patterns that were
simply misused and where the developers who used them
During our work we have developed a simple procedure had clearly not understood the rationale behind the
to guide the removal of inappropriate patterns from code. pattern. In the second category are patterns that do not
This is clearly an eclectic practitioner's approach that has fall into the first category, but which did not match the
evolved and succeeded during our project, but it is no project's set of quality criteria at the time of reviewing.
comprehensive and systematic solution to the problem. To Step 4: It is important to carry out this assessment
We found the following steps helpful (cf. [ 121): in the light of the quality criteria (Step 1). For example,
enhanced flexibility of a design due to the use of a
Step 1: Identify the relevant quality attributes for the pattern is only beneficial if flexibility is a relevant quality
software under consideration. criterion. Moreover one should clarify the underlying
Step 2: Identify patterns used in the code. idea of flexibility: Is the particular form of flexibility
Step 3: Try to reconstruct the original rationale behind offered by the pattern really the desired one? Another
the use of patterns. important aspect of flexibility is that it is a potential
Step 4: Assess the concrete benefit of a pattern. benefit, i.e. it becomes beneficial only if it is actually
Step 5: Assess the concrete extra cost of a pattern. used. Therefore the likelihood that a flexibility potential
Step 6: Assess the total effort needed to remove the is really used one day should be included in the
pattern. assessment. If this likelihood is close to zero, then the
Step 7: Make a balanced decision based on Steps 4, 5, benefit of the pattern is negligible as well.
and 6 whether to remove the pattern. To Step 5: Again it is important to carry out this
assessment in the light of the quality criteria (Step 1). We
To Step 1: Usually the detailed information system used a very simple approach based on two ratings. 'The
strategy of the company or project should provide some first rating was the subjective degree of additional
hints on the quality strategy. In our project the official complexity introduced by a pattern, which was rated on
plans for the system do not envisage substantial an ordinal scale (low, medium, high). The second rating
functional enhancements for the future. Therefore issues assessed the relevance for software developers to
like extensibility and flexibility are minor issues. On the understand the bit of code containing the pattern, again
other hand the product must be maintained by a small rated on an ordinal scale (low, medium, high). The
team of maintenance engineers that were not involved in resulting assessment matrix gives a clear overview of the
the development phase, and therefore low complexity of patterns with reference to possible removal. The idea
the code is a major concern to ensure maintainability. behind the assessment matrix is that patterns with a high
To Step 2: Identifying patterns in the code turned out degree of additional complexity that affect code that must
to be cumbersome at times. Often combinations of be understood by many software developers are clear
patterns had been used, which often led to a blurred candidates for removal.
separation of concepts. The same applies to variants of To Step 6: A major determinant of the effort needed
patterns, that were often difficult to tell. On top of that to remove a pattern from code is the degree of coupling it
come simple errors in the application of patterns that exhibits to other parts of the system. We only regarded
impede their identification: For example we found one simple aspect of coupling, namely the number of files
affected by the removal of a pattern, i.e. the number of
82
files of which a new version would be checked into the lopers wanted to gain experience with patterns. Fourth,
configuration management system as a result of the the cookbook style of much of the patterns literature
pattern's removal. Admittedly this simplistic measure for tempted to embellish a pattern with additional features.
the software quality attribute coupling is very coarse, and Therefore it happend that features were added because
it was primarily chosen for pragmatic reasons, because it they were mentioned in books, not because they were
can be calculated using the dependency checking actually needed.
mechanism of an ordinary compiler. Unfortunately we One major impediment to our work was the lack of
did not have more sophisticated tools at our disposal. appropriate documentation of early design decisions in
To Step 7: The decision to include a pattern in favour of patterns. We believe that software developers
program code is to some extend a subjective one, and who fail to record these crucial decisions have simply not
naturally the same applies to the removal of a pattern. understood the informing ideas behind patterns.
Nevertheless we have found one rule of thumb very We have presented a simple procedure consisting of
helpful: Don't give a pattern the benefit of the doubt. seven steps that we have used during the identification,
assessment, and removal of obsolete patterns. This proce-
5. Conclusions dure has led to more objective, well-documented, and
economically sound decisions during our reengineering
The intention of this paper is not to criticise the idea of activies. Nevertheless the decision to remove a pattern
patterns, instead it is motivated by the observation that inevitably remains subjective to some degree.
the inappropriate application of patterns can possibly In the course of our work we identified several cases
backfire. We have presented several examples where of inappropriate patterns where their removal would not
proven and popular patterns have been applied by have been viable. Often these patterns are strongly
professional designers and programmers, probably with coupled to other software artefacts, giving rise to com-
the best of intentions. These examples show that this has plex dependencies and possible side effects.
led to negative results in some cases. Therefore we This paper is drawn on the experience gained in a
believe that inappropriately applied patterns will be a single project, albeit a very large one. We believe that the
relevant aspect of software reengineering and main- situation described in this paper may apply to a consi-
tenance in the future. derable proportion of the software developed during the
The benefits of patterns are eagerly acknowledged in 90s, the heydays of patterns. If that is true, then we have
the literature, but the associated costs feature less to be prepared to deal with inappropriately applied
prominently. Naturally patterns affect different software patterns in the future. This leads the way for future
quality attributes, and the application of a pattern may for research into the subject from a reengineering pers-
example result in a desirable increase of flexibility at the pective. First, we need a more objective assessment of the
cost of an undesirable increase of complexity. Therefore cosvbenefit ratio of patterns. Second, we need more
the use of patterns is not a "free lunch". Accordingly it guidance in the decision when to remove a pattern from
can make economic sense to remove an inappropriate code. Third, we should develop systematic procedures
pattern from code. and tool support for the removal of inappropriate patterns
We have found two categories of inappropriately from code.
applied patterns in our project. In the first category are
patterns that were simply misused by software developers 6. References
who had not understood the rationale behind the patterns.
In the second category are patterns that do not fall into [ l ] Beck, K. et al., "Industrial Experience with Design
the first category, but which do not match the project's Patterns", Proceedings of the 18th International Conference on
requirements. Software Engineering, IEEE Computer Society Press, 1996, pp.
Our analysis of patterns in the second category has 103-1 14.
identified a number of situations that gave rise to inap-
[2] Beck, K., Extreme Programming Explained: Embrace
propriate patterns. First, many software developers rou- Change, Addison-Wesley,2000.
tinely overestimated the future volatility of requirements,
and often opted for patterns to build flexibility into the [3] Buschmann, F. et al., Pattern-Oriented Software Archi-
software. Second, requirements changed over the lifetime tecture: A System of Patterns, John Wiley & Sons, 1996.
of the project, and thereby patterns that had been reason-
able at first became obsolete later. Third, in some cases [4] Casais, E., "Re-Engineering Object-Oriented Legacy
patterns were applied without any regard to the quality Systems", The Journal of Object-Oriented Programming, Vol.
goals of the project, for example because software deve- 10, NO. 8, 1998, pp. 45-52.
83
[5] Dodani, M., “Rules Are for Fools, Pattems Are for Cool [9] Grand, M., Pattems in Java (Vol. I), Wiley & Sons, 1998.
Fools”, The Journal of Object-Oriented Programming, Vol. 12,
NO. 6, 1999, pp. 21-23, p. 70. [lo] Pfleeger, S . L. et al., “Status Report on Software
Measurement”, IEEE Software, MarchlApril 1997, pp. 33-43.
[6] Fowler, M. et al., Refactoring: Improving the Design of
Existing Code, Addison-WesleyLongman, 1999. [ I l l Prechelt, L. et al., “A Controlled Experiment in
Maintenance Comparing Design Patterns to Simpler Solutions”,
[7] Gamma, E. et al., Design Patterns: Elements of Reusable To appear in IEEE Transactions on Software Engineering,
Object-Oriented Software, Addison-Wesley Publishing http://wwwipd.ira.uka.de/-prechelt/Biblio/.
Company, 1995.
[I21 Pressman, R. S . , Software Engineering - A Practitioner’s
(81 Gillies, A., Software Quality: Theory and Management, Approach, McGraw-Hill Companies, 1997.
InternationalThomson Computer Press, 1997.