Docstoc

repetition

Document Sample
repetition Powered By Docstoc
					                    design
                Editor: Martin Fowler         s   T h o u g h t Wo r k s    s   fowler@acm.org




Avoiding Repetition
Martin Fowler




                            oftware design is not easy—not easy            and removing repetition can lead to many




                    S       to do, teach, or evaluate. Much of
                            software education these days is
                            about products and APIs, yet much
                            of these are transient, whereas good
                            design is eternal—if only we could
                    figure out what good design is.

                    Searching for design principles
                       One of the best ways to capture and pro-
                                                                           interesting consequences. I have an increas-
                                                                           ing sense that a pig-headed determination to
                                                                           remove all repetition can lead you a long
                                                                           way toward a good design and can help you
                                                                           apply and understand the patterns that are
                                                                           common in good designs.

                                                                           A simple case: subroutine calls
                                                                               Take a simple example: subroutine calls.
                                mulgate good design is to learn            You use a subroutine when you realize that
                                from the patterns community.               two blocks of code, in different places, are
                                Their work, especially the famous          or will be the same. You define a subroutine
                                book Design Patterns (E. Gamma             and call it from both places. So, if you
                                et al., Addison Wesley, Reading,           change what you need to, you don’t have to
                                Mass., 1994), has become a cor-            hunt down multiple repetitions to make the
                                nerstone for many designers of             change. Granted, sometimes the duplication
                                object-oriented software. Pat-             is just a coincidence, so you wouldn’t want
                                terns are not easy to understand,          a change in one to affect the other—but I
                                but they reward the effort of              find that is rare and easy to spot.
                                study. We can learn from the spe-              So what if the blocks are similar but not
                                cific solutions they convey and            identical? Maybe some data is different in
                    from the thinking process that leads to their          the two cases. In that case, the answer is ob-
                    development. The thinking process is hard to           vious: you parameterize the data by passing
                    grasp, but understanding it helps us discover          in arguments to a subroutine. One block of
                    principles that often generate these patterns.         code that multiplies by five and another
                       Over the last year, I’ve been struck by one         that multiplies by 10 become one block that
                    of the underlying principles that leads to             multiplies by x, and you replace x with the
                    better designs: remove duplication. It’s also          right number.
                    been highlighted by mantras in a couple of                 That’s a simple resolution but it illus-
                    recent books: the DRY (don’t repeat your-              trates a basic principle that carries over into
                    self) principle in the Pragmatic Programmer            more complicated cases. Identify what is
                    (A. Hunt, and D. Thomas, Addison Wesley,               common and what varies, find a way to iso-
                    1999) and “Once and Only Once” from Ex-                late the common stuff from the variations,
                    treme Programming Explained: Embrace                   then remove the redundancy in the common
                    Change (K. Beck, Addison Wesley, 1999).                stuff. In this case, separating the commonal-
                       The principle is simple: say anything in            ity and the variability is easy. Many times it
                    your program only once. Stated blandly like            seems impossible, but the effort of trying
                    that, it hardly bears saying. Yet identifying          leads to good design.

                                                                                   January/February 2001   IEEE SOFTWARE   97
                                                              DESIGN
                                                            DEPT TITLE


What’s the same and what’s
                                                 class Invoice...
different?
    What if two routines have the                     String asciiStatement() {
same basic flow of behavior but dif-                    StringBuffer result = new StringBuffer();
fer in the actual steps (see Figure 1)?                 result.append(“Bill for “ + customer + “\n”);
These two routines are similar, but                     Iterator it = items.iterator();
not the same. So, what is the same                      while(it.hasNext()) {
and what is different?                                       LineItem each = (LineItem) it.next();
    The sameness is the routine’s over-                      result.append(“\t” + each.product() + “\t\t”
all structure, and the differences are in                      + each.amount() + “\n”);
                                                        }
the steps. In both cases, the structure is
                                                        result.append(“total owed:” + total + “\n”);
                                                        return result.toString();
s    print some header for the invoice,               }
s    loop through each item printing a
     line, and
s    print a footer for the invoice.                  String htmlStatement() {
                                                        StringBuffer result = new StringBuffer();
As Figure 2 shows, we can separate                      result.append(“<P>Bill for <I>” + customer + “</I></P>”);
the two by coming up with some kind                     result.append(“<table>”);
of printer notion with a common in-                     Iterator it = items.iterator();
terface for header, footer, and lines                   while(it.hasNext()) {
                                                             LineItem each = (LineItem) it.next();
and an implementation for the ASCII
                                                             result.append(“<tr><td>” + each.product()
case. Figure 3a shows that the com-
                                                               + “</td><td>” + each.amount() + “</td></tr>”);
mon part is then the looping structure,                 }
so we can wire the pieces together as                   result.append(“</table>”);
shown in Figure 3b.                                     result.append(“<P> total owed:<B>” + total + “</B></P>”);
   There’s nothing earth-shattering                     return result.toString();
about this solution; just apply a poly-               }
morphic interface—which is common
to any OO or component-based envi-
                                               Figure 1. Two similar routines with different steps.
ronment that lets you easily plug in
multiple implementations of a com-
mon interface. Design Patterns
junkies will recognize the Template
                                                      interface Printer {
Method pattern. If you are a good de-
                                                        String header(Invoice iv);
signer and are familiar with polymor-                   String item(LineItem line);
phic interfaces, you could probably                     String footer(Invoice iv);
come up with this yourself—as many                    }
did. Knowing the pattern just gets
                                                (a)
you there quicker. The point is, the
desire to eliminate duplication can                   static class AsciiPrinter implements Printer {
lead you to this solution.                               public String header(Invoice iv) {
                                                           return “Bill for “ + iv.customer + “\n”;
Duplication and patterns                                 }
   Thinking in terms of duplication                      public String item(LineItem line) {
and its problems also helps you un-                        return “\t” + line.product()+ “\t\t” + line.amount() + “\n”;
derstand the benefits of patterns.                       }
Framework folks like patterns be-                        public String footer(Invoice iv) {
cause they easily let you define new                       return “total owed:” + iv.total + “\n”;
pluggable behaviors to fit behind the                    }
                                                       }
interface. Eliminating duplication
helps because as you write a new im-            (b)
plementation, you don’t have to
worry about the common things that
need to be. Any common behavior                Figure 2. (a) A common interface for header, footer, and lines and
should be in the template method.              (b) an implementation for the ASCII case (try the HTML case as an
This lets you concentrate on the new           exercise on your own).

98     IEEE SOFTWARE   January/February 2001
                                     DESIGN



  class Invoice...
    public String statement(Printer pr) {
      StringBuffer result = new StringBuffer();
      result.append(pr.header(this));
      Iterator it = items.iterator();
      while(it.hasNext()) {                                                                                           How to
                                                                                                                     Reach Us
           LineItem each = (LineItem) it.next();
           result.append(pr.item(each));
      }
      result.append(pr.footer(this));
      return result.toString();
    }
                                                                                                              Writers
                                                                                                               For detailed information on submitting articles,
  (a)                                                                                                          write for our Editorial Guidelines (software@
                                                                                                               computer.org), or access computer.org/
  class Invoice...                                                                                             software/author.htm.
    public String asciiStatement2() {
      return statement (new AsciiPrinter());                                                                  Letters to the Editor
    }                                                                                                           Send letters to
  (b)                                                                                                                   Letters Editor
                                                                                                                        IEEE Software
Figure 3. (a) The common part of the routine and (b) the pieces
                                                                                                                        10662 Los Vaqueros Circle
wired together.
                                                                                                                        Los Alamitos, CA 90720
                                                                                                                        dstrok@computer.org
                                                                                                                Please provide an e-mail address or
behavior rather than the old.              structures, you are more likely to                                   daytime phone number with your letter.
   The principle of duplication also       spot any duplication in the routines.
helps you think about when to apply        Much of the reason why objects are                                 On the Web
this pattern. As many people know,         popular is because of this kind of so-                              Access computer.org/software for information
one of the problems with people who        cial effect, which works well when                                  about IEEE Software.
have just read a pattern is that they      reinforced by a culture that encour-
insist on using it, which often leads to   ages people to look around and fix                                 Subscription Change of Address
more complicated designs. When you         duplications when they do arise.                                    Send change-of-address requests for magazine
insist on using a pattern, ask, “What                                                                          subscriptions to address.change@ieee.org.
repetition is this removing?” Remov-                                                                           Be sure to specify IEEE Software.
ing repetition makes it more likely            o, avoiding repetition is a simple
that you’re making good use of the
pattern. If not, perhaps you shouldn’t
use it.
                                           S   principle that leads to good de-
                                               sign. I intend to use this column
                                           to explore other simple principles
                                                                                                              Membership Change of Address
                                                                                                               Send change-of-address requests for the mem-
                                                                                                               bership directory to directory.updates@
                                                                                                               computer.org.
   Often, the hard part of eliminat-       that have this effect. Have you no-
ing duplication is spotting it in the      ticed simple principles like this in
first place. In my example, you can        your work? If so, please contact                                   Missing or Damaged Copies
spot the two routines easily because       me—I’m always happy to repeat                                       If you are missing an issue or you received
they are in the same file and located      good ideas.                                                         a damaged copy, contact membership@
close to each other. What happens                                                                              computer.org.
when they are in separate files and
written by different people in differ-                                                                        Reprints of Articles
ent millennia?                                                                                                 For price information or to order reprints, send
   This question leads us to think                                                                             e-mail to software@computer.org or fax +1
                                           Martin Fowler is the chief scientist for ThoughtWorks, an
about how we construct our soft-           Internet systems delivery and consulting company. For a decade,     714 821 4010.
ware to reduce the chances of this         he was an independent consultant pioneering the use of objects
happening. Using abstract data types       in developing business information systems. He’s worked with
                                           technologies including Smalltalk, C++, object and relational
                                                                                                              Reprint Permission
is a good way of doing this. Because       databases, and Enterprise Java with domains including leasing,      To obtain permission to reprint an article, con-
you have to pass data around, you          payroll, derivatives trading, and healthcare. He is particularly    tact William Hagen, IEEE Copyrights and Trade-
find that people are less likely to du-    known for his work in patterns, UML, lightweight methodologies,
                                           and refactoring. He has written four books: Analysis Patterns,
                                                                                                               marks Manager, at whagen@ieee.org.
plicate data structures. If you try to     Refactoring, Planning Extreme Programming, and UML Distilled.
place routines next to their data          Contact him at fowler@acm.org.


                                                                                                              January/February 2001    IEEE SOFTWARE         99