0% found this document useful (0 votes)
19 views40 pages

AntiPatterns and Refactoring

The document discusses AntiPatterns in software development and architecture, defining them as bad ideas that hinder effective design and implementation. It emphasizes the importance of refactoring, which is the process of improving code readability, maintainability, and extensibility without altering its external behavior. The document also highlights various 'code smells' that indicate the need for refactoring, ultimately advocating for its necessity in maintaining high-quality software.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
19 views40 pages

AntiPatterns and Refactoring

The document discusses AntiPatterns in software development and architecture, defining them as bad ideas that hinder effective design and implementation. It emphasizes the importance of refactoring, which is the process of improving code readability, maintainability, and extensibility without altering its external behavior. The document also highlights various 'code smells' that indicate the need for refactoring, ultimately advocating for its necessity in maintaining high-quality software.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 40

AntiPatterns and Refactoring

Everything from(W. Howden and Dan Fleck Slides)


Definitions
• Pattern: good ideas
• AntiPatterns: bad ideas
• Refactoring: better ideas
Kinds of AntiPatterns
• AntiPatterns, W.H. Brown et al, Wiley,
1998
  Software Development
  Software Architecture
– Software Project Management
Software Development
Anti-Patterns
• Control Freak
• Old Baggage
• Functional Fixation
• Gadget Clutter
• Golden Hammer
• Clipboard Coding
Control Freak
• Description
– large object with all the control, which accesses simple
data classes
God Class
– essentially a procedural design

• 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

• The goal of refactoring is NOT to add new


functionality
• The goal is refactoring is to make code easier
to maintain in the future
Refactoring Simple Example
Move a method:
Motivation: A method is, or will be, using or used by more features of
another class than the class on which it is defined.
Technique: Create a new method with a similar body in the class it uses
most. Either turn the old method into a simple delegation, or remove it
altogether.
Danger!
• Refactoring CAN introduce problems,
because anytime you modify software you
may introduce bugs!
• Management thus says:
– Refactoring adds risk!
– It’s expensive – we’re spending time in
development, but not “seeing” any external
differences? And we still have to retest?
Why are we doing this?
Motivation
• We refactor because we understand getting the
design right the first time is hard and you get
many benefits from refactoring:

– Code size is often reduced


– Confusing code is restructured into simpler code
– Both of these greatly improve mainatainability!
Which is required because requirements always
change!
Refactoring Example: Replace Conditional with
Polymorphism

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?

• Martin Fowler uses “code smells” to identify


when to refactor.

• Code smells are bad things done in code,


somewhat like bad patterns in code

• Many people have tied code smells to the


specific refactorings to fix the smell
Code Smells
• Duplicated Code
– bad because if you modify one instance of
duplicated code but not the others, you (may)
have introduced a bug!
• Long Method
– long methods are more difficult to understand
– performance concerns with respect to lots of
short methods are largely obsolete
Code Smells
• Large Class
– classes try to do too much, which reduces cohesion
• Long Parameter List
– hard to understand, can become inconsistent
• Divergent Change
– Related to cohesion: symptom: one type of change
requires changing one subset of methods; another
type of change requires changing another subset
Code Smells
• Lazy Class
– A class that no longer “pays its way”
• e.g. may be a class that was downsized by a previous
refactoring, or represented planned functionality that
did not pan out
• Speculative Generality
– “Oh I think we need the ability to do this kind of
thing someday”
• Temporary Field
– An attribute of an object is only set in certain
circumstances; but an object should need all of its
attributes
Code Smells
• Data Class
– These are classes that have fields, getting and setting
methods for the fields, and nothing else; they are
data holders, but objects should be about data AND
behavior
• Refused Bequest
– A subclass ignores most of the functionality
provided by its superclass
– Subclass may not pass the “IS-A” test
• Comments (!)
– Comments are sometimes used to hide bad code
• “…comments often are used as a deodorant” (!)
Many more code smells
• Many more smells at:
– http://c2.com/cgi/wiki?CodeSmell

• Given a smell, what refactorings are likly?


– http://wiki.java.net/bin/view/People/
SmellsToRefactorings
SMELLS EXAMPLE – See which smells you find in the sample code
Duplicated Code
Long Method
Large Class
Long Parameter List
Divergent Change- Related to cohesion: symptom: one type of change requires changing
one subset of methods; another type of change requires changing another subset
Data Class - These are classes that have fields, getting and setting methods for the fields, and
nothing else; they are data holders, but objects should be about data AND behavior
Refused Bequest - A subclass ignores most of the functionality provided by its superclass
Comments (!) - Comments are sometimes used to hide bad code
Lazy Class - A class that no longer “pays its way”
Speculative Generality - “Oh I think we need the ability to do this kind of thing someday”
Temporary Field - An attribute of an object is only set in certain circumstances; but an
object should need all of its attributes
Why use them?
• Code smells and refactoring are techniques to
help you discover problems in design and
implementation and apply known solutions to
these problems

• Should they be used all the time? You should


always think about them, but only apply them
when they make sense… sometimes you need a
long method… but think about it to make sure!
Adding safety
• Remember that making these changes
incurs some risk of introducing bugs!
• To reduce that risk
– You must test constantly – using automated
tests wherever possible
• http://www.refactoring.com/catalog/index.html
– Use tools! Netbeans and Eclipse both support
basic refactoring
(http://wiki.netbeans.org/Refactoring)
Question from your boss
"Refactoring is an overhead activity - I'm paid to write new,
revenue generating features."
• Tools/technologies are now available to allow refactoring
to be done quickly and relatively painlessly.
• Experiences reported by some object-oriented
programmers suggest that the overhead of refactoring is
more than compensated by reduced efforts and intervals in
other phases of program development.
• While refactoring may seem a bit awkward and an
overhead at first, as it becomes part of a software
development regimen, it stops feeling like overhead and
starts feeling like an essential.
Quoted from: http://st-www.cs.illinois.edu/users/opdyke/wfo.990201.refac.html
Quoted from: http://st-www.cs.illinois.edu/users/opdyke/wfo.990201.refac.html
Summary
• Refactoring improves the design of software
– without refactoring, a design will “decay” as people make
changes to a software system
• Refactoring makes software easier to understand
– because structure is improved, duplicated code is
eliminated, etc.
• Refactoring helps you find bugs
– Refactoring promotes a deep understanding of the code at
hand, and this understanding aids the programmer in
finding bugs and anticipating potential bugs
• Refactoring helps you program faster
– because a good design enables progress
References
• Comic from:
http://www.irregularwebcomic.net/cgi-bin/co
mic.pl?comic=687
• http://www.refactoring.com/catalog/index.html
• http://www.cs.colorado.edu/~kena/classes/
6448/s05/lectures/lecture18.pdf
• http://www.codeproject.com/KB/architecture/
practicalexp.aspx

You might also like