What are Development AntiPatterns?
(for a quick example, see the website's featured Development AntiPattern, Lava Flow)
Our first exposure to software development AntiPatterns was through the presentations
of Mike Akroyd, a hands-on software consultant to Motorola and other major firms [Akroyd
96]. The Akroyd AntiPatterns define classic problems in object-oriented software
design. Some of the development AntiPatterns in this book are extensions of his
concepts (see references). One attractive feature of all Akroyd AntiPatterns is the
inclusion of a refactored solution, the incorporation of which gives AntiPatterns
a valuable purpose: Not only to they point out trouble, but they also tell you how to get
out of it.
Proper AntiPatterns define a migration (or refactoring) from negative solutions to
positive solutions. AntiPatterns that describe only the negative solution are called
pseudo-AntiPatterns (or more typically, complaints -- think of
pseudo-AntiPatterns as flaming e-mail diatribes). After working with the Akroyd
AntiPatterns, we discovered examples of AntiPatterns and pseudo-AntiPatterns on the
Internet. The Pattern Languages of Program Design (PLoP) conference also discussed
some AntiPattern-related papers, such as the "Big Ball of Mud" [Foote 97].
A key goal of development AntiPatterns is to describe useful forms of software
refactoring. Software refactoring is a form of code modification, used to improve
the software structure in support of subsequent extension and long-term maintenance.
In most cases, the goal is to transform code without impacting correctness.
Good software architecture is essential for system extension and maintenance.
Software development is a chaotic activity, therefore the implemented structure of systems
tends to stray from the planned structure as determined by the architecture, analysis and
design. Software refactoring is an effective approach for improving software
structure. The resulting structure does not have to resemble the original planned
structure. The structure changes because programmers learn constraints and
approaches that alter the context of the coded solutions. When used properly,
refactoring is a natural activity in the programming process. For example, the
solution for the Spaghetti Code AntiPattern discussed in this book defines a software
development process that incorporates refactoring.
Refactoring is strongly recommended prior to performance optimization.
Optimizations often involve compromises to program structure. Ideally, optimizations
affect only small portions of a program. Prior refactoring helps to partition
optimized code from the majority of the software.
Read more about refactoring, and formal refactoring transformations in our book in
||Lack of clarification of the modeling viewpoint
leads to problematic ambiguities in object models.
||Always clarify which of the 3 essential viewpoints is
modeled: business, specification, or implementation.
technology is purchased by a systems development project that goes unused.
||Send competent engineers to the product training course, in
order to evaluate, before you buy the product.
technology releases surpasses our ability to keep up and keep other technologies
||Depend upon stable technologies and interfaces that you
control. Open systems standards provide stability.
|Cut and Paste
||Code reused by copying source
statements leads to significant maintenance problems.
||Black Box reuse reduces maintenance issues by
having a common source code, testing, and documentation for multiple reuses.
modification of commercial software or reusable software creates significant maintenance
burdens for a software system.
||Avoid modification of supported software. Choose
mainstream, supported products and platforms whenever possible.
||Management waits until the last possible moment
to allow developers to proceed with design and implementation; then they want results
||Proactive design and prototyping are often warranted; even
if customers and management staff are not completely on-board.
||Non-OO design (possibly from legacy) is coded in OO
language and notation.
||Since there is no straightforward way to
refactor: redesign using OO principles.
||A familiar technology or concept is applied obsessively to
||Expanding the knowledge of developers through
education, training, and book study groups exposes developers to new solutions.
||Custom-programmed input algorithms contain many
bugs which are easily encountered by users and testers.
||Utilize production-quality input processing techniques,
including lexical analysis, parser generators, and features matrices.
||Dead code and forgotten design information is frozen in an
||Configuration control processes that eliminate
dead code and evolve/refactor design towards increasing quality.
||Keep the developers in dark and feed them
fertilizer. End-user interaction prohibited.
||Risk-driven development includes frequent user-interaction
to maximize usability and acceptance.
||Classes with a very limited roles and lifecycles, often
starting processes for other objects.
||Allocate the responsibility to longer-lived
objects and eliminate the poltergeists.
||Procedural-style design leads
to one object with numerous responsibilities and most other objects only holding data.
||Refactor the design to distributed
responsibilities more uniformly and isolate the effect of changes.
|Walking Through a Mine Field
technology is much less robust than people imagine; bugs are pervasive and potentially
||Proper investment in software testing and inspection is
needed to reduce the frequency and density of software defects.