Simulated Inheritance (Switch Statement)


Symptoms

  • Code uses a switch statement ( especially on a type field).

  • Code has several if statements in a row (especially if they're comparing against the same value).

  • Code uses instanceof (or its equivalent) to decide what type it's working with.

Causes

This smell is often caused by laziness in introducing new classes. The first time you need conditional behavior, you might use an if or switch statement rather than a new class. It's not a big problem at this point because it occurs only once. Then say you need another condition based on the same type code, and you introduce a second switch instead of fixing the lack of polymorphism.

Sometimes the lack of polymorphism is hidden behind a series of if statements instead of an explicit switch statement, but the root problem is the same.

What to Do

Don't simulate inheritance ”use mechanisms built into the programming language.

  • If a switch statement on the same condition occurs in several places, it is often using a type code ; replace this with the polymorphism built into objects. It takes a series of refactorings to make this change:

    1. Extract Method. Pull out the code for each branch.

    2. Move Method. Move related code onto the right class.

    3. Replace Type Code with Subclass or Replace Type Code with State/Strategy. Set up the inheritance structure.

    4. Replace Conditional with Polymorphism. Eliminate the conditionals.

  • If the conditions occur within a single class, you might be able to replace the conditional logic via Replace Parameter with Explicit Methods or Introduce Null Object .

Payoff

Improves communication. May expose duplication.

Contraindications

Sometimes a switch statement is the simplest way to express the logic. If the code is doing something simple, in one place, you may not feel the need for a separate class. This may be especially common for places that are interfacing with non-object-oriented parts of the system. Michael Feathers says, "I'm okay with switches if they convert data into objects."

A single switch statement is sometimes used in a Factory or Abstract Factory (for more information, see Gamma's Design Patterns ). This one place decides how to configure the whole factory. You can sometimes replace it with Class.forName() (i.e., dynamic class loading), but that is not always attractive for security, communication, or performance reasons.

Sometimes a switch statement is used in several related places to control a state machine. Decide whether it makes more sense as is, or whether the State pattern (see Gamma's Design Patterns ) is more appropriate.

Exercise 22 Switch Statement.

Consider this code:

 public void printIt(Operation op) {     String out = "?";     switch (op.type) {     case '+': out = "push"; break;     case '-': out = "pop"; break;     case '@': out = "top"; break;     default: out = "unknown";     }     System.out.println("operation=" + out); } public void doIt(Operation op, Stack s, Object item) {     switch (op.type) {     case '+': s.push(item); break;     case '-': s.pop(); break;     } } 
  1. What would you do?

See Appendix A for solutions.

Exercise 23 Factory Method. (Challenging).

Consider this class structure:

graphics/07inf01.gif

  1. Write code for the factory according to the implied design. Note: One of the three constants is passed to the constructor; this determines what type driver will be returned by getDriver() .

  2. Your code probably smells of a switch statement (even if it's implemented using if ). Is this conditional logic justified?

  3. Some factories use dynamic class loading ”via Class.forName() ”to load the correct class on demand. Modify your factory to accept a string argument (the name of the driver class) and load the instance dynamically. Your code no longer mentions the types explicitly. What are some advantages to that? (Hint: Think of the impact on building the system.)

  4. What are some disadvantages to this new arrangement?

See Appendix A for solutions.




Refactoring Workbook
Refactoring Workbook
ISBN: 0321109295
EAN: 2147483647
Year: 2003
Pages: 146

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