DRY

advertisement
DRY
11: DRY—Don’t Repeat Yourself
• Every piece of knowledge should have a single,
unambiguous, authoritative representation within a
system
• Duplication is evil!
• Why?
– Things change
– If you have the same thing in several places, when you
change one, you have to change all the others
– And you can’t always find them all!
What not to duplicate
• Data
– If you represent the same data in two places (or
in two ways), you have just taken on the job of
keeping the two representations in agreement
• Code
– If you code the same task in two places (or in
two ways), you have just taken on the job of
keeping the two code segments in agreement
How duplication arises
• Same information must be represented in
many ways, or in several places
• Required by documentation standards
• Required by the language
• As a result of bad design
• Taking shortcuts
• Poor communication among team members
Multiple copies of data
• Sometimes the same information must be
stored in two places (say, a client and a
server)
• Sometimes you need the same information
in two different programming languages
• Best solution: Have one authoritative
repository, and generate all the needed
copies from it
– Remember, programs can create code
Example
• Suppose you must have a table of numbers in your
program, and also in a document
– Solution #1: Add code to your program to write out the
table in a form you can use in the document
– Solution #2: Same as #1, but hot link to the table from
your document (if possible)
– Solution #3: Write a program that takes the table from
the document and produces code you can insert into
your program
– Solution #4: Keep the master table in a separate place,
and generate both the program and the document
Documentation standards
• Comments should not repeat code
– They should add higher-level information—what the
code is doing, and why, but not how it does it
• If code requires explanation, it’s bad code—fix it!
• Your documentation should agree with your code
– Untrustworthy comments are worse than none
– This is much easier if your comments are high level
– This is why javadoc is so wonderful—it’s always
correct!
Language requirements
• Some languages, such as Ada, require you
to duplicate information
– Ada has:
• An interface part, where you provide all the
function headers
• An implementation part, where you provide all
the functions (with the same headers)
– The advantage is that it forces you to hide the
implementation from the users
– The disadvantage is that you need the identical
information in two places
• There’s not much you can do about this
Bad design
• A Truck has a capacity, a license number,
and a driver
• A DeliveryRoute has a route, a Truck,
and a driver
• One of our drivers calls in sick and we need
to change drivers
– Where do we change this information?
– Solution: Refactor (redesign) the program!
Copy-paste programming
• Suppose, as you are coding, you find you need to
do the same thing as you did somewhere else
– So you take this shortcut: you copy and paste code
• Later you find you need to do almost the same
thing again
– So you copy the code, paste it in, and adjust it
• Later still, you find you need to change that code
– Which copies are the same, and which almost the same?
• Never take a shortcut when you’re in a hurry!
How to avoid copy-paste
• Often the best solution is to write a method
– Call the method whenever you want to perform
the computation
– There is nothing wrong with short methods
• If you want to do almost the same thing,
parameterize (add parameters to) the
method
Duplication for efficiency
• Suppose you have this class:
class Point {
double x, y;
...
}
• And you discover that some of your users want to
have polar coordinates (ρ and θ)
• You can’t discard x and y, because the class is
already in use
• So you end up with double x, y, rho, theta;
• Now what if a user changes, say, x?
Meyer’s Uniform Access Principle
•
•
Bertrand Meyer: “All services offered by a
module should be available through a
uniform notation, which does not betray
whether they are implemented through
storage or through computation.”
Translation into Java:
1. Make your variables private
2. Use getters and setters
Redoing the Point example, I
• Suppose you had started with:
class Point {
private double x, y;
void setX(double x) { this.x = x; }
void setY(double y) { this.y = y; }
double getX() { return x; }
double getY() { return y; }
}
• Does this help solve the problem?
Redoing the Point example, II
• To add ρ and θ:
– Do not add fields rho and theta; instead, do
double getRho() { return Math.sqrt(x*x + y*y); }
double getTheta() { return Math.acos(x / rho); }
void setRho(double rho) {
x = rho * Math.cos(theta);
y = rho * Math.sin(theta);
}
void setTheta(double theta) {
x = rho * Math.cos(theta);
y = rho * Math.sin(theta);
}
– Is there anything else that needs to be done?
– Can you think of another way to do this?
Poor communication
• Different team members might implement the
same functionality
• How do we avoid this?
– Good communication!
•
•
•
•
Exchange ideas with co-workers
Read your co-workers code
Let others read your code
Have code walkthroughs
– Have a clear design
– Have a strong technical project leader
– Have a clearly understood division of responsibilities
12: Make it easy to reuse
• Your co-workers won’t use your code
unless:
– They know about it
– It’s easy to access
– It’s easier to use your code than to write their
own version of the same thing
• You won’t even reuse it yourself unless:
– It’s easy to use
– It’s general enough to support reuse
Summary
• DRY—Don’t repeat yourself!
– This principle is so important that I’ve given
almost an entire set of slides to it
• Make it easy to reuse
The End
Download