< Day Day Up > |
You often work with more than one instance of an object. You can aggregate those instances using an array or a collection class. I like to distinguish between two types of aggregations. The first is termed a group , the second a collection . A group is a set of objects, typically coded using an array or a linked list. When I use the [] symbol in a class description, I am implying a group, not necessarily a particular implementation of a group. A collection is a set of objects, typically implemented by a collection class or template ( Vector , List , etc.). Operations on a collection can include performing an operation on the collection as a whole, such as calculating the average value of an attribute for all objects in the collection, or finding a particular object matching a key value. If you find you are performing more operations on a group, other than just passing it to other methods or enumerating it, you might want to turn it into its own class. Creating a specific collection class, instead of using classwide (static) methods, separates the concerns of operations on all the objects in a collection, from those operations on a single object. [*]
For example, suppose that Sam wanted to keep track of the rental history of each CDDisc . You could keep the history of each rental in a RentalHistory object: class RentalEvent Timestamp time_started Timestamp time_end Dollar rental_fee class CDDisc RentalEvent [] rental_history. If the only value Sam wanted to know was the number of times a CDDisc had been rented, there is no need for a collection. The number of times is simply the length of rental_history . However, if additional operations are to be performed with rental_history , it is time to make the attribute into its own class. For example, you might want to know the average time period for a rental, the shortest or longest rental, or the total revenue from the CDDisc. You can create a RentalHistory class to represent a collection of RentalEvent s and add these methods to that class: class RentalHistory Count number_of_rentals( ) Dollar total_revenue( ) Days short_rental( ) Days longest_rental( ) The representation of a collection should be separate from the use of the collection. At coding time, RentalHistory can either be derived from a regular or a templated library class, or it can delegate its operations to an attribute that represents a library collection class. Likewise, CDDisc s exist within a CDDiscCollection . In Sam's Checkout_CDDisc and Return_CDDisc use cases, we need to find a CDDisc by its physical ID. Tim and I create a CDDiscCollection interface, which looks like this: interface CDDiscCollection CDDisc find_by_physical_id(PhysicalID a_physical_id) CDDisc [] find_by_cd_release(CDRelease a_cd_release) // Standard collection operations: add(CDDisc a_cd_disc) remove (CDDisc a_cd_disc) CDDiscCollection hides the implementation of how the collection is organized. In the actual implementation, we might use a library collection class, a database, or even a text file.
|
< Day Day Up > |