10.5 Reuse by Copy

 < Day Day Up > 



10.5 Reuse by Copy

Reuse by copy is perhaps the most prevalent way that reuse of common functionality is accomplished. It is not magical; a programmer finds some lines of code in a program that achieves some necessary behavior and copies the block of code, possibly modifying it slightly for the new situation, to another place in the program or even to a completely different program. The example of reuse by copy shown in Exhibit 1 (Program10.1) is similar to the programs that move balls in Chapter 8, but in this case we have only one ball. The ball simply sets up a path to move from the top of the screen to the bottom of the screen and then back again. Note that the code to wait for the ball to finish moving is copied twice in the program, an obvious case for abstracting this behavior into a function.

Exhibit 1: Program10.1: Reuse by Copy

start example

 import java.awt.*; import java.util.*; import animator.*; public class ConcurrentBall implements DrawListener, Runnable {  private Path myPath;  private Animator animator;  /** Constructor. Note that we need to register with the   *  animator through the run method.   */  public ConcurrentBall(Animator animator) {    this.animator = animator;  }  /**   * The run method simulates an asynchronous ball. The   * myPath variable is set here and used in the draw method   * and is intended to coordinate the ball thread running in   * this method and the GUI thread (from the animator)   * running in the draw method. This works correctly.   */  public void run() {    // Set an initial point to draw this object, and then add it    // to the animator.    myPath = new StraightLinePath(10, 205, 10, 205, 1);    animator.addDrawListener(this);    Random random = new Random(System.currentTimeMillis());    try {      // Note that this block of code is copied twice in this      // program. All that is changed is the actual path that      // is created. It would be best to abstract out this      // behavior.      while(true) {        synchronized(this) {          try {            myPath = new StraightLinePath(410, 205, 10, 205,              50);            wait();          } catch(InterruptedException e) {          }        }        Thread.sleep(random.nextInt(10000));        synchronized(this) {          try {            myPath = new StraightLinePath(10, 205, 410, 205,              50);            wait();          } catch(InterruptedException e) {          }        }        Thread.sleep(random.nextInt(10000));      }      } catch (InterruptedException e) {      }    }    /**     *  Draw is called each time through the animator loop to draw     *  the object. It simply uses the path to calculate the     *  position of this object and then draws itself at that     *  position. When the end of the path is reached, it notifies     *  the ball thread.     */    public synchronized void draw(DrawEvent de) {      Point p = myPath.nextPosition();      Graphics g = de.getGraphics();      g.setColor(Color.red);      g.fillOval((int)p.getX(),  (int)p.getY(),  15,  15);      if (! myPath.hasMoreSteps())        notify();    }    /**     * The main method just creates the animator     * and the ball threads and starts them running.     */    public static void main(String args[]) {      Animator animator = new Animator();      ConcurrentBall cb1 = new ConcurrentBall(animator);      (new Thread(cb1)).start();      animator.setVisible(true);    } } 

end example

In Exhibit 1 (Program10.1), we now have two copies of the code to move the ball in the run method, each one doing largely the same thing. Later, if the procedure is needed again, another copy can be made. This continues until this same piece of code is spread throughout a program or, worse, many programs. It might be changed slightly in each of its incarnations, even in such minor details as variable names used, so it could be difficult to even identify all of the places in the program it is being used.

This type of reuse, while common, is not a good method for reusing code. It has a number of disadvantages:

  • Every time a new copy of a method is made, it must be managed. The more copies of redundant code that exist, the bigger the problems in managing the overall program or systems.

  • If a bug is ever found in the copied code, that bug must be fixed everywhere that code is used. This can become a daunting task, as there is likely no documentation on all the places this code is used. Also, because it could be modified slightly each time it is used, it might be very difficult to find and fix all the occurrences of this bug.

  • Frequently used behaviors can often be used effectively if the programmers know they exist; however, the presence of reuse by copy hides these commonly used behaviors in the actual program code, so they are difficult to find and catalog. Therefore, many programmers on a project will not know that a problem has been previously solved and will redevelop a solution to an already solved problem. These solutions will vary greatly in effectiveness and efficiency and, because they are very different, cannot be easily optimized. By abstracting this frequently used code out into separate methods or objects, it is easier to identify, catalog, use, and optimize the behaviors in these methods.

  • Poorly structured programs often result. Instead of a single function call, the copied code could be several dozen lines of code, sometimes with complex logic, branches, or looping inside of it. Copying it into an already complex program can make the program longer and further obfuscate the purpose and procedure of the program. Being able to summarize a section of code with a single method call often makes it easier to understand the role it plays in an algorithm and the overall role of the algorithm in which it is used.

Reuse by copy is not a good solution to the reuse problem. Much better ways to achieve reuse are covered in the next three sections and provide better reuse characteristics than reuse by copy.



 < Day Day Up > 



Creating Components. Object Oriented, Concurrent, and Distributed Computing in Java
The .NET Developers Guide to Directory Services Programming
ISBN: 849314992
EAN: 2147483647
Year: 2003
Pages: 162

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net