< 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.
10.6.1. Placing LimitsOne 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 CodeThe 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.
|
< Day Day Up > |