10.6. Something Working

 <  Day Day Up  >  

The search interface we implemented is basic. It provides the needed functionality. We know that we might need to refine it. We could get bogged down in refinement details before creating the first implementation. Instead of doing that, when we have ideas for additional improvements while developing the first interface, we write them down in the design journal for later development.

The basic catalog lookup is working. The number of items returned by a given search criterion might be large. For example, if the user typed in the letter A or the word The , a large number of songs would be matched. The match processing could put restrictions on searches for common words. However, a large number of matches still would be possible. The display widget (e.g., a drop-down list or a web page) could have difficulty showing a large number of matches. We could refine the search mechanism to provide a limiting feature.

GET SOMETHING WORKING

Create something basic before adding refinements . [*]


[*] Danny Faught notes that although this is the key to being agile, "Before agile, I remember a suggested integration technique, taking a path from the top of the module hierarchy down to the bottom (with few side trips), so you can run an end-to-end test early on."

10.6.1. Placing Limits

One approach to the problem of dealing with a large number of matches is to place a hard limit on the number of matches. Placing limits on operations can be useful in getting something working. However, unnecessary limits on operations can be annoying to the user.

Instead of placing a hard limit on the number of matches, we can code our system to deal with large numbers of matches in small, easily handled batches. To that end, we wrap another interface around CDCatalogItemCollection . The methods in this new class parallel the methods in CDCatalogItemCollection . For example:

 interface CDCatalogItemSearchByBatch         CDCatalogItemSearchResults search_for_cd_catalog_items_by_title (             CommonString string_to_match)         CDCatalogItemSearchResults retrieve_cd_catalog_item s_for_a_performer(             Performer a_performer)             // and the other methods 

The methods in CDCatalogItemSearchByBatch return objects of CDCatalogItemSearchResults . A CDCatalogItemSearchResults object works like an iterator, except it returns a batch of CDCatalogItem s, not just a single CDCatalogItem . The class looks like this:

 class CDCatalogItemSearchResults         private CDCatalogItem [] results     // From the search.         Boolean has_more_items( )         CDCatalogItem [] get_next_batch(int number_to_get) 

The user calls has_more_items( ) to see if there are any remaining items. Then he calls get_next_batch( ) with the number of items desired. get_next_batch( ) returns null if there are no more items.

This is another example of "Separating Concerns Makes Smaller Concerns." The CDCatalogItemCollection class does not have to worry about keeping track of how many items were already returned as matches. CDCatalogItemSearchByBatch does not have to worry about how to find the matches.

10.6.2. Common Code

The ability to iterate through a set of matching items seems appropriate for Songs and Performers . Therefore, we create additional classes ( SongSearchResults and PerformerSearchResults ) that are used to return batches of matches. The SongSearchResults and PerformerSearchResults classes have the same logic as CDCatalogItemSearchResults . The implementation of each class could delegate to a helper class the job of keeping track of which batch to return.

Since they differ only by the data type on which they operate , a mechanism for creating the duplicate logic seems appropriate. Templates and preprocessing code are two ways of creating this logic. A template is in the form of:

 template <Item>     {     class SearchResults         {         private Item [] results;  // From the search.         Boolean has_more_items( );              // next call to get_next_batch will return items         Item [] get_next_batch(int number_to_get);         }     } 

We can use this template by specifying other text to replace the "Item" token. For example, we can declare:

 SearchResults<CDCatalogItem> cd_catalog_item_search_results; 

A call to a method for this object, such as cd_catalog_item_search_results.get_next_batch( ) , returns an object of type CDCatalogItem [].

If the implementation language supports templates, we use that approach. If it does not, we can create a base source-code file and use a script to perform the substitution. The script can be part of the build process.

The template approach (either language based or script based) permits a set of code to be reused without cut and paste.

USE THE SAME LAYOUT TO GET THE SAME LAYOUT [*]

Use templates or scripts for classes and methods to create consistent logic .


[*] The page at http://www.ambysoft.com/typesOfReuse.html describes a wide range of reusable stuff.

 <  Day Day Up  >  


Prefactoring
Prefactoring: Extreme Abstraction, Extreme Separation, Extreme Readability
ISBN: 0596008740
EAN: 2147483647
Year: 2005
Pages: 175
Authors: Ken Pugh

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