AntiPatterns and Refactoring
AntiPatterns and Refactoring
• Consequences
– difficult to modify functionality
– not based on domain model
– difficult to test and reuse
Old Baggage
• Description
– system contains many classes whose purpose is not
known
• Lava Flow, Dead Code
– much of the code is left over from previous ideas and
no longer has a purpose
• was once fluid and useful, now is solid lava that you are afraid
to remove
• Consequences
– difficult to maintain, just gets worse
Functional Fixation
• Description
– main top level routine
– main calls other routines that have been made into
objects/classes
– top down development
• Functional Decomposition
• Consequences
– class models make no sense
– no O/O benefits such as inheritance and polymorphism
Gadget Clutter
• Description
– transient, ghost-like (no state) classes whose objects are
created to perform some temporary responsibility
• Proliferation of classes
– unnecessary abstractions that clutter the design
• Consequences
– clutter up the design
– non-object oriented classes with names like “start up
counter”, “initialize data base”
Golden Hammer
• Description
– a particular technology or product is used for
everything because a development team has
gained proficiency in it.
• Consequences
– may leave out awkward but necessary features
– system architecture fits the preordained solution
rather than the problem domain
Spaghetti
• Description
– well known bad detailed design feature for functional
code – rats nest of control flows
– O/O: objects are basically functions and there is little
interaction. Single process control weaving its way in
and out of objects
• Consequences
– difficult to maintain and understand, lack of code re-use
opportunities, does not have an underlying domain
model
Clipboard Coding
• Description
– re-use of code within a system
– re-use of code from other systems
– generally a good idea but can be over-used, and without
due caution
• Consequences
– bug duplication
– incomplete required modification of re-used code
– failure to identify and create re-usable classes, etc.
Software Architecture
Anti-Patterns
• Coincidental Architecture
• Cover Your Assets
• Bondage and Submission
• Assumed Architecture
• Platypus
• I Did it My Way
Coincidental Architecture
• Terminology and variations
– combining things in a way that is driven by their properties rather than by a
comprehensive idea for an architecture
– needs constant repairs, patches and adhoc pieces
• Stovepipe
– Types of:
• Migration: moving to distributed system
• System: subsystems integration
• Enterprise: multiple non-matching, layered systems
Cover Your Assets
• Description
– avoid making decisions
– list all the alternatives
• paralysis by analysis
– course of action not clear
• Consequences
– not clear what the present and future architecture will
be
– documents will not be used
Bondage and Submission
• Descriptions
– Architecture based on a product line such as
Visual Studio
• Vendor lock-in
• Consequences
– lack of control over future product upgrades
– mixed product versions
– commercial product updates drive maintenance
Assumed Architecture
• Description
– no specified architecture
• wherefore art thou architecture?
– usually similar to experience on previous systems
– turns out to be too big/complex to do informally
• Consequences
– hidden risks, misunderstood requirements, problems
with backup and contingency plans
Platypus
• Description
– designed by a committee
• design by committee, political party, standards
disease
– everyone had to be accommodated
– poorly run meetings
• Consequences
– overly verbose, incoherent, no prioritization
I Did it My Way
• Description
– Lack of design re-use, i.e. not the same as not re-using
the wheel
• re-inventing the wheel, design in a vacuum
– Failure to carry out domain analysis to find essential
features
– Lack of legacy design documents
• Consequences
– replication of commercial software
– Immature and unstable architectures
Refactoring
• Periodically need to clean up the design and the
code
• Related to idea of developing code for base
increment, and then modifying it for subsequent
phases
• Refactoring goals
– improve cohesion, reduce coupling
• Reference: Martin Fowler, Refactoring, Addison-
Wesley, 2000
Why do good developers write
bad software?
• Requirements change over time, making it
hard to update your code (leading to less
optimal designs)
• Time and money cause you to take shortcuts
• You learn a better way to do something (the
second time you paint a room, it’s always
better
Two than the first because you learned
questions:
1.How do we fix our software?
during
2. the
How do we first
know our time!)
software is “bad”… when it works
fine!
Refactoring
• Definition: Refactoring modifies software to
improve its readability, maintainability, and
extensibility without changing what it
actually does.
• External behavior does NOT change
• Internal structure is improved
Refactoring
Motivation: You have a conditional that chooses different behavior depending on the type of
an object.
Technique: Move each leg of the conditional to an overriding method in a subclass. Make
the original method abstract.
double getSpeed() {
switch (_type) {
case EUROPEAN:
return getBaseSpeed();
case AFRICAN:
return getBaseSpeed() - getLoadFactor() * _numberOfCoconuts;
case NORWEGIAN_BLUE:
return (_isNailed) ? 0 : getBaseSpeed(_voltage);
} throw new RuntimeException ("Should be unreachable");
}
Refactoring Example: Replace Conditional with
Polymorphism
When do I refactor?
• When you add functionality
– Before you add new features, make sure your
design and current code is “good” this will help
the new code be easier to write
• When you need to fix a bug
• When you do a peer review
How do I identify code to refactor?