Designing with Extensibility in Mind

 <  Day Day Up  >  

Adding new features to a class might be as easy as extending an existing class, and adding a few new methods and modifying the behavior of others. It is not necessary to rewrite everything. This is where inheritance comes into play. If you have just written a Person class, you must consider the fact that you might later want to write an Employee class, or a Vendor class. Thus, having Employee inherit from Person might be the best strategy; in this case, the Person class is said to be extensible . You do not want to design Person so that it contains behavior that prevents it from being extended by classes such as Employee or Vendor ( assuming , of course, that in your design you really intend for other classes to extend Person ). For example, you would not want to code functionality into an Employee class that is specific to supervisory functions. If you did, and then a class that does not require supervisory functionality inherited from Employee , you would have a problem.

This point touches on the abstraction guideline discussed earlier. Person should contain only the data and behaviors that are specific to a person. Other classes can then subclass it and inherit appropriate data and behaviors.

What Attributes and Methods Can Be Static?

It is important to decide what attributes and methods can be declared as static. Revisit the discussions in Chapter 3 on using the static keyword to understand how to design these into your classes.


Making Names Descriptive

Earlier we discussed the use of proper documentation and comments. Following a naming convention for your classes, attributes, and methods is a similar subject. There are many naming conventions, and the convention you choose is not as important as choosing one and sticking to it. However, when you choose a convention, make sure that when you create classes, attributes, and method names, you not only follow the convention, but make the names descriptive. When someone reads the name, he should be able to tell from the name what the object represents.

Good Naming

Make sure that a naming convention makes sense. Often, people go overboard and create conventions that might make sense to them, but are totally incomprehensible to others. Take care when forcing other to conform to a convention. Make sure that the conventions are sensible and that everyone involved understands the intent behind them.


Making names descriptive is a good development practice that applies to more than just OO development.

Abstracting Out Nonportable Code

If you are designing a system that must use nonportable code (that is, the code will only run on a specific hardware platform), you should abstract this code out of the class. By abstracting out, we mean isolating the nonportable code in its own class. For example, if you are writing code to access a serial port, you should create a wrapper class to deal with it. Your class should then send a message to the wrapper class to get the information or services it needs. Do not put the system-dependent code into your primary class (see Figure 5.5).

Figure 5.5. A serial port wrapper.

graphics/05fig05.gif

If the class moves to another hardware system, the way to access the serial port changes, or you want to go to a parallel port, the code in your primary class does not have to change. The only place the code needs to change is in the wrapper class.

Providing a Way to Copy and Compare Objects

Chapter 3 discusses the issue of copying and comparing objects. It is important to understand how objects are copied and compared. You might not want, or expect, a simple bitwise copy or compare operation. You must make sure that your class behaves as expected, and this means you have to spend some time designing how objects are copied and compared.

Keeping the Scope as Small as Possible

Keeping the scope as small as possible goes hand-in-hand with abstraction and hiding the implementation. The idea is to localize attributes and behaviors as much as possible. In this way, maintaining, testing, and extending a class are much easier.

Keeping Scope as Small as Possible

Minimizing the scope of global variables is a good programming style, and not specific to OO programming.


For example, if you have a method that requires a temporary attribute, keep it local. Consider the following code:

 
 public class Math {     int temp=0;     public int swap (int a, int b) {         temp = a;         a=b;         b=temp;         return temp;     } } 

What is wrong with this class? The problem is that the attribute temp is only needed within the scope of the swap() method. There is no reason for it to be at the class level. Thus, you should move temp within the scope of the swap() method:

 
 public class Math {     public int swap (int a, int b) {         int temp=0;         temp = a;         a=b;         b=temp;         return temp;     } } 

This is what is meant by keeping the scope as small as possible.

A Class Should Be Responsible for Itself

In a training class based on their book, Java Primer Plus , Tyma, Torok and Downing propose the class design guideline that all objects should be responsible for acting on themselves whenever possible. Consider trying to print a circle.

First, let's use a non-OO example. The print command finds Circle and prints it (see Figure 5.6):

 
 print(circle); 
Figure 5.6. A non-OO example of a print scenario.

graphics/05fig06.gif

print , draw , and other functions need to have a case statement (or something like an if/else structure) to determine what to do for the given shape passed. In this case, a separate print routine for each shape could be called.

Every time you add a new shape, all the functions need to add the shape to their case statement.

Now let's look at an OO example. By using polymorphism and grouping the Circle into a Shape category, Shape figures out that it is a Circle and knows how to print itself (see Figure 5.7):

 
 Shape.print(); // Shape is actually a Circle 
Figure 5.7. An OO example of a print scenario.

graphics/05fig07.gif

 <  Day Day Up  >  


Object-Oriented Thought Process
Object-Oriented Thought Process, The (3rd Edition)
ISBN: 0672330164
EAN: 2147483647
Year: 2003
Pages: 164
Authors: Matt Weisfeld

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