Exercise 35 Walking a List.

Consider the code used in Exercise 4 (Chapter 3).

  1. How is walking the list of machines a case of Feature Envy or Inappropriate Intimacy?

  2. Address this by extracting a new class. Make sure it has a report() method.

See Appendix A for solutions.

Exercise 36 Middle Man. (Challenging).

Consider these classes:

(This code has been greatly simplified; the queue wasn't originally storing strings.)

 import java.util.ArrayList;

public class Queue {
     ArrayList delegate = new ArrayList();
     public Queue() {}
     public void addRear(String s) {delegate.add(s);}
     public int getSize() {return delegate.size();}

     public String removeFront() {
         String result = delegate.get(0).toString();
         return result;
} (selection)

 public void testQ() {
     Queue q = new Queue();
     assertEquals("E1", q.removeFront());
     assertEquals("E2", q.removeFront());
     assertEquals(0, q.getSize());
  1. Remove Middle Man so that the queue is no longer a middle man for the ArrayList. Is this an improvement?

  2. Put the Middle Man back in via Hide Delegate .

See Appendix A for solutions.

Exercise 37 Cart. (Challenging).

Consider these classes:


Here is Cart.cost():

 public int cost() {
   int total = 0;
   for (int i=0; i < purchases.size(); i++) {
      Purchase p = (Purchase) purchases.elementAt(i);
      total += p.item().cost + p.shipping().cost;
   return total;
  1. Write the implied classes (and tests). The maxDays() method computes the largest number of days for any ShippingOption in the purchase.

  2. Apply Hide Delegate so Cart accesses only Purchase directly.

  3. Hide Delegate causes the Middle Man (Purchase) class to have a wider interface; that is, it exposes more methods . But applying that refactoring can open up a way to make the interface narrower. Explain this apparent contradiction.

  4. Use this line of reasoning to narrow the Purchase interface.

  5. Notice that the primitive int type is used to represent money. Would it be easier to introduce a Money class before or after the delegate changes?

See Appendix A for solutions.

Exercise 38 Trees in Swing. (Challenging).

In Swing, JTree is in the javax.swing package, and TreeModel and DefaultTreeModel are in the javax.swing.tree package. (The table classes have a similar organization.)


  1. Explain how the TreeModel interface breaks the dependency between JTree and DefaultTreeModel.

  2. Explain how there are still dependencies at the package level.

  3. Suppose each package corresponds to a library (this is an oversimplification). Explain a way to break the package dependency so that JTree could be shipped in a library independent of DefaultTreeModel.

  4. Systems today ship with so much disk space; why should anybody worry about library dependencies?

See Appendix A for solutions.

Chapter 11. Accommodating Change

Some problems become most apparent when you try to change your code. (Most of the other smells we've discussed can be detected by looking at the code statically.)

Ideally, one changed decision affects only one place in the code. When it doesn't work out that way, it's a sign of duplication in the code.

Addressing these smells often has a side benefit: Many times it makes the code easier to test.