Designing with Maintainability in Mind

 <  Day Day Up  >  

Designing useful and concise classes promotes a high level of maintainability. Just as you design a class with extensibility in mind, you should also design with future maintenance in mind.

The process of designing classes forces you to organize your code into many ( ideally ) manageable pieces. Separate pieces of code tend to be more maintainable than larger pieces of code (at least that's the idea). One of the best ways to promote maintainability is to reduce interdependent code ”that is, changes in one class have no or minimal effects on other classes.

Highly Coupled Classes

Classes that are highly dependent on one another are considered highly coupled . Thus, if a change made to one class forces a change to another class, these two classes are considered highly coupled. Classes that have no such dependencies have a very low degree of coupling. For more information on coupling, refer to The Object Primer by Scott Ambler.


This means that changes should only be made to the implementation of an object. Changes to the public interface should be avoided at all costs. Any changes to the public interface will cause ripple effects throughout all the systems that use the interface.

For example, if a change were made to the getName() method of the Cabbie class, every single place in all systems that use this interface must be changed and recompiled. Simply finding all these method calls is a daunting task.

To promote a high level of maintainability, keep the coupling level of your classes as low as possible.

Using Iteration

As in most design and programming functions, using an iterative process is recommended. This dovetails well into the concept of providing minimal interfaces. A good testing plan quickly uncovers any areas where insufficient interfaces are provided. In this way, the process can iterate until the class has the appropriate interfaces. This testing process is not simply confined to coding. Testing the design with walkthroughs and other design review techniques is very helpful. Testers' lives are more pleasant when iterative processes are used, because they are involved in the process early and are not simply handed a system that is thrown over the wall at the end of the development process.

Testing the Interface

The minimal implementations of the interface are often called stubs . (Gilbert and McCarty have a good discussion on stubs in Object-Oriented Design in Java .) By using stubs, you can test the interfaces without writing any real code. In the following example, rather than connect to an actual database, stubs are used to verify that the interfaces are working properly (from the user 's perspective ”remember that interfaces are meant for the user). Thus, the implementation is really not necessary at this point. In fact, it might cost valuable time and energy to complete the implementation at this point, because the design of the interface will affect the implementation, and the interface is not yet complete.

In Figure 5.8, note that when a user class sends a message to the DataBaseReader class, the information returned to the user class is provided by code stubs, and not by the actual database. (In fact, the database most likely does not exist yet.) When the interface is complete and the implementation is under development, the database can then be connected and the stubs disconnected.

Figure 5.8. Using stubs.

graphics/05fig08.gif

Here is a code example that uses an internal array to simulate a working database (albeit a simple one):

 
 public class DataBaseReader {     String db[] = { "Record1",         "Record2",         "Record3",         "Record4",         "Record5"};     boolean DBOpen = false;     int pos;     public void open(String Name){         DBOpen = true;     };     public void close(){         DBOpen = false;     };     public void goToFirst(){         pos = 0;     };     public void goToLast(){         pos = 4;     };     public int howManyRecords(){         int numOfRecords = 5;         return numOfRecords;     };     public String getRecord(int key){         /* DB Specific Implementation */         return db[key];     };     public String getNextRecord(){         /* DB Specific Implementation */         return db[pos++];     }; } 

Notice how the methods simulate the database calls. The strings within the array represent the records that will be written to the database. When the database is successfully integrated into the system, it will then be substituted for the array.

Keeping the Stubs Around

When you are done with the stubs, don't delete them. Keep them in the code for possible use later. In fact, in a well-designed program, your test stubs should be integrated into the design and kept in the program for later use. In short, design the testing right into the class!


As you find problems with the interface design, make changes and repeat the process until you are satisfied with the result.

 <  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