The following terms, although of less philosophical importance than the essential terms, are nonetheless commonly
Collaboration
and
collaborator
are terms referring to a particular type of object cooperation and the object relied upon for that cooperation. Objects are social and convivial things, constantly exchanging messages with one another and cooperating to complete
Collaboration occurs when
Object A receives a request for one of its advertised services.
While in the process of
Object B is
not
an object occupying one of object A s instance
Object B becomes the collaborator , a covert assistant to object A.
The exchange between object A and object B occurs inside the encapsulation barrier of the object. It s this covert aspect that makes this particular exchange different from all other object-object messaging. Collaboration is an aspect of how an object satisfies a request. Collaborations always involve some degree of coupling between both parties of the collaboration, so the number of collaborations should be minimized to the greatest extent possible.
Class
is a
a label for a set of similar objects
an exemplar object
a storage location for knowledge (rare) or behavior mechanisms that are identical for all
an object factory
Following is an
Class as set.
An application of the principle of aggregation, noted in Chapter 4, a class is a
Class as exemplar object.
A confusing (for the beginner) but common practice is to use the terms
class
and
object
interchangeably, with the context indicating which is
Class as storage location.
This use of the term is relevant only in the context of software objects. The mechanisms that allow an object to fulfill its responsibilities are, in the case of software objects, blocks of implementation language code. It s more efficient, both in terms of physical storage and, more important, in terms of maintenance, to store such a mechanism in one place: in the class. Instances of the class are given access to the common mechanism when required. In the real world, this use of class does not normally occur because storage and maintenance are not usually important issues. All human beings, for example, have bits of neural tissue that, when activated, allow them to respond to the message, What is your
Class as object factory. This is another metaphor, which states that a class has the responsibility of creating new objects, new instances of the class. To do this, it needs a specification for an instance (an object). When we define a class, we commingle what are really two definitions, one for the class itself and one for the objects it will be responsible for creating. This will be clarified later in the definition of implementation terms.
A class hierarchy, or class library, is the taxonomic organization of a group of classes. In some implementation languages (Smalltalk), this is an organized hierarchy, while in others (C++), it might be a simple shared library with no hierarchy except compilation dependencies. A class hierarchy should,
The organization of a class hierarchy ”the is-a-
| Note |
The example presented here uses various types of collections, which might seem a poor choice because collections do not occur in most domains ”as collections. If we are seeking an object, we are likely to be looking for something with a common domain name ”a customer or a product, for example. Collections are ubiquitous in every domain, albeit with different
|
Always remember that the hierarchy is based on behavior and that classes lower in the hierarchy are assumed to extend the behavior of those above them in their branch of the hierarchy.
Abstract and concrete are labels for classes that do not have instances and those that do, respectively. In creating a taxonomy, it s convenient and sometimes necessary to create a class solely for the purpose of representing (and in software taxonomies, storing) behavior common to two or more other classes. These classes are not intended to have instances. Concrete classes have instances, so by definition, all objects are instances of concrete classes.
Abstract classes are always parent classes. An abstract class should not appear below a concrete class in the hierarchy.
In languages lacking explicit taxonomic relationships among classes (in C++, for example, where the classes are simply members of a library with no explicit enforcement of the is-a-kind-of relationship, as is the case in Smalltalk), an abstract class represents a template for a set of
Inheritance is
There are actually three different inheritance metaphors, two suggested by biology and one by economics. In biology, a child inherits the genes of both of its parents and hence shares some traits and capabilities based on its parentage. Biology also suggests the possibility of creating global structure that shows how the is-a-kind-of relationship connects all living things. This structure is called a taxonomy , and the one you are most likely to be familiar with was established by Carolus Linnaeus. The third metaphor is suggested by our practice of allowing relatives to inherit the resources of their parents.
All three metaphors have been used to explain inheritance. As discussed in Chapter 4, object thinking uses the idea of a taxonomy tree based on an is-a-kind-of relationship as long as characteristics and behaviors are used as the criteria for establishing the relationship. Object thinking explicitly rejects the idea of basing a class hierarchy based on DNA ”the internals of an object, such as its methods or its instance variables. The definition of inheritance then becomes, A superordinate-subordinate relationship between classes in which the subordinate (child) has the same behaviors (responsibilities) as the superordinate (parent) plus at least one additional.
The compiler or interpreter behind your implementation programming language needs instructions on how to actually implement the inheritance relationship ”how to search parent classes for methods or variables not physically present in the child class. In some languages, this mechanism is automatic and
When classes have one and only one parent, they are said to participate in a scheme of
single inheritance
. Classes may have a grandparent, great grandparent, and so on, but the entire lineage is based on the fact that a class has only one parent on the
Figure 5-5:
Inheritance tree fragment, showing both single and multiple inheritance.
The italicized entries in the classes represent messages that can be sent to objects of that class to obtain an object holding the information
Inheritance can be visualized as
In another example,
aStudent
is sent the
name
message. This time, the inheritance mechanism does not find the
Inheritance is assumed to be intrinsically slow because it must execute machine cycles to conduct its search for the appropriate method. The apparent slowness is eliminated through optimization in all but the most severely time-constrained applications. What happens if
aWorkStudyStudent
is sent the message
salary
? A long search chain begins with a query to the
WorkStudyStudent
class, the
Student
class, the
Person
class, and then the
Object
class, all with no results. Having reached the top of the hierarchy, the search returns to
WorkStudyStudent
and then to its second parent,
Employee
, where the method is found and made accessible. Multiple inheritance increases the potential length of the search chain and
An even more
Now suppose that it s 3:00 a.m. , and aWorkStudyStudent is in the vault at the Federal Reserve Bank. The requesting object is a security guard who wants to make sure the student is authorized to be in the vault. When aWorkStudyStudent returns her student ID, she is likely to be arrested. This situation can occur because classes can have identical message signatures in their protocols. (See the definition of polymorphism a little later on.)
Multiple inheritance is unnecessary. Object thinkers consider it a bad idea. It s unnecessary because there are always design alternatives (such as delegation, discussed in the next section) that remove the apparent need. It s a bad idea because it needlessly complicates the process of providing objects with access to the methods that allow them to respond to messages. It s a bad idea because it introduces the potential for error and confusion when the wrong mechanism with the correct name is used. It s a bad idea because it necessitates any object participating in a multiple-inheritance relationship to know who might send a message (for example, the
yourIdPlease
message) and to determine which of its inherited IDs (employee or student) it should return to which client. Or the client must know about the internal structure of the object it s talking to and determine whether it should ask for employee.id or student.id. In both cases, the communicating objects are tightly
Object thinking will almost always provide alternative solutions to any design problem that at first seems to
|
|
Hi, Hector, we need to talk about these stories if you have some time.
Sure, glad to help. Should we stand over there by the whiteboard?
Yeah. Hector and two pairs of programmers head for the whiteboard. Sally and Suroor are working on your story about updating inventory, and June and I are working on the ˜menu displays available products story, Ron introduces the subject of the conversation. During the stand-up this morning, we started talking about the two stories and thought we saw some overlap ”for example, both the menu and the
inventoryReorderList
need to know what products have been sold and if any are left. So we went out to Vending Row and tried to visualize what exactly goes on in both stories by looking at or
Sounds interesting. Shoot.
OK, I ll start, and the others can jump in when they wish. Let me draw on the board. [Figure 5-6 shows the sketch Ron puts on the whiteboard.] Here we have the central object in these stories ”the dispenser. Visualize the
Figure 5-6:
Hector s rough sketch of the objects the group is talking about, which he has made so that he has something to point to while telling the stories.
We all think there should be some kind of ˜stock dispensers story, interjected Sally. We watched the guy from the vendor company loading the
But the first one gets contents in a second way, continues Suroor. When a product is dispensed, the dispenser pushes the next product in line into the first position. All the other products get advanced as well. Now, the reorder list doesn t care about this event ”it already has the item in its list from the time the vending machine was stocked. All it cares about is the event occurring when a product is dispensed.
The menu, on the other hand, does want to know which new product has arrived in this spot. So it registers to be notified of any productReplaced event that occurs in the currentProduct slot. It then asks the product coming into that slot for its name, which it adds to the appropriate spot on itself for display.
When a product is dispensed, adds June, the
inventoryList
wants to know as well. It actually needs to be notified of a
readyToDispense
event so it can ask the product for its ID before it s
Ron takes the stage again. When the inventoryList is asked to transmit itself back to the home office, it tells all the line items to execute its reorderAmountRule . Then all the information in the four fields is ready for transmission: each product ID to be reordered, the amount sold since the last time the reorderList was requested, the amount to be reordered, and the average time on the shelf in that machine.
But that s not part of our story ”the two Sals are working on that one.
Hector looks puzzled for a second. Oh, you mean Sally and Salvatore. Gotcha.
There is another special case, Suroor says. If a product is put in the
currentProduct
slot and it has
Seems to me you have it nailed. Hector
Well, Ron replies, we already have a dispense product story; we just need to make sure that the pair working on it know about the needs of the
Menu
and the
reorderList
. And I think that the update
reorderList
is just part of the need we should
OK, I ll write the stock dispensers story and put it in the hopper for the next iteration. We can just amend the narrative on the update inventory story you already have to reflect our discussion. The same is true of the update menu story. Those can stay in this iteration, then, and keep the same priority ”unless you think this will
No, if anything, it will make it easier, so we should finish in less time than originally estimated when we didn t really know what we were going to do, Ron says as the others nod in agreement.
And, continues Hector, I will talk with the dispense product coders and make sure we have not changed their story so much we blow their estimate. Good work, and thanks for the suggestions. I think this better captures what happens and what we want in the final software.
|
|
Delegation is a way to extend or restrict the behavior of objects by composition rather than by inheritance.
Consider an investment portfolio. A portfolio must be able to add and delete investments, return a subset of investments (all the
Delegation is one way to address the apparent need for multiple inheritance in the case of a
workStudyStudent.
A
workStudyStudent
object could contain within itself an instance of
Employee
and an instance of
Student
. It could then define its own interface so that messages best handled by the
anEmployee
object could be forwarded to the instance variable containing that object. The same would apply to messages most appropriately handled by the
aStudent
object. Delegation eliminates the need for servers to be aware of their
An object might want to advertise an ability to play different roles, and this too can be addressed with delegation. The
workStudyStudent
might, instead of creating its own protocol as a superset of
Employee
and
Student
,
Delegation is used extensively in objectlike languages such as Visual Basic and is a generally useful technique that was too often overlooked when inheritance was being stressed as fundamental to object implementation.
When I send a message to an object, it has complete leeway to interpret that message as it sees fit. The receiver of the message decides the appropriate response and how to respond. As a sender of the message, none of that is my concern. Because each object can interpret a message any way it wants (as long as its protocol tells me what kind of object I can expect in return when sending the message), more than one object can respond to an identical message.
Because every object has the right to define its own interface protocol, it is not unusual for two or more objects to adopt the same message signatures. A photograph and a document might both choose to implement a print message. The details of printing will be quite different for the two objects, as will the results. One message can yield many different responses, depending on whom it was sent to. Thinking of each response as a form of response, we have one message yield many forms (of response). The Greek for form is morph , and poly used as a prefix means many ” hence polymorphism (many forms). A bit of a stretch, but that is where the term comes from.
Making the receiver of the message responsible for its interpretation gives me a great deal of freedom in how I work with mixed objects. I can talk with objects in ordinary vernacular. For example, I can ask them to print
Polymorphism is a completely unremarkable
In the case of software objects, message signatures are supposed to capture the essence of the message so that potential senders will know how to select the appropriate message and object for their purposes. Good names are in limited supply, and many objects in quite different areas of the class hierarchy will have similar behavioral needs. Both students and
The personal integrity of objects should not be violated. This is such an important principle that the defining term,
encapsulation
, might better be
Every object has a boundary separating public and private realms. This is true whether the object is a software construct or a person. That boundary is held to be impermeable: even though we know it can be penetrated, it should not be. Encapsulation defines the insides (structural definition and enabling mechanisms) of an object as private space, to or of which no one except the object itself should have access or knowledge.
In most ways, encapsulation is a discipline more than a real barrier. Seldom is the integrity of an object protected in any absolute sense, and this is
Encapsulation implies more than respecting the public/private boundary. Object users should not make assumptions about what is behind the barrier either. This is true whether the assumption is about a piece of knowledge that might be stored in the object or about the details of any message response mechanisms that might be inside the object. Just because an object indicates that it can provide a bit of information doesn t
It is frequently the case that an object will be given responsibilities for maintaining and providing bits of information that it does not possess. As a typical human object, for example, I have a responsibility to remember the names and birth dates of my family members. I do a reasonably good job of remembering the names because I have memorized them: they are somehow part of my internal memory structure. I do not remember the dates. An external planner object, containing a page object, which lists my family members and important dates associated with each one, is a very
A
component
is a large-grain object made up of several basic objects. A roof truss is an example of a component. It s made up of 2 — 6 pieces of lumber and gang
The distinction among an object, a component, an application, and a system is somewhat arbitrary, however clearly defined advocates may define each term. All can be called objects because all are packages of behavior with an external interface and all, even the most basic object, might contain other objects.
Framework is another term with multiple meanings. The four most common are implementation (for example, a set of GUI widgets); foundational (a partial solution to a problem encountered in multiple applications or domains), an implemented pattern (for example, resource allocation); application , or vertical market application (for example, banking); and architectural (for example, client/server).
An implementation framework is a collection of classes that collectively capture the behavior of a small, specialized domain. Examples might include a graphics framework or a money framework. At this level, the framework consists almost exclusively of a set of classes, a small class hierarchy that can be added to a development environment.
An abstract, or
foundational
, framework is both a collection of classes and the scripts that guide their typical interaction. A foundational framework offers an abstract solution to a particular problem that might be encountered in
Application frameworks are customizable solutions to common domain needs. They are also known as vertical market frameworks. Examples would include an inventory control framework, an accounting framework, and a demand deposit framework. This kind of framework is a completely functional software solution but one that is easily edited (not reprogrammed) into a custom solution for a specific client.
Architectural
frameworks are the most general, and might better be thought of as architectural
patterns
. Examples would include client/server, model-view-controller, pipes and filters,
Pattern is a term with one description and at least two meanings. The common description is, A named solution to a recurring problem-in-context that has instructional value. The original meaning of pattern came from Christopher Alexander and reflected his focus on the problem space ”a pattern was observable in the world, it could be described, and the description could be used to replicate the pattern when useful. The most common meaning of the term comes from the book Design Patterns , by the Gang of Four (GoF) ”Erich Gamma, Richard Helms, Ralph Johnson, and John Vlissides ”for whom a pattern is a programming design solution to a recurring programming problem.
Most of the people using the term have been inspired by the work of Christopher Alexander, an architect who proposed a
pattern language
of design parameters that would allow the construction of anything from an independent region to a montage of photos on the wall of a
Alexander s goal was the discovery of the principles behind a Timeless Way of Building, including structural, organizational, and
Richard Gabriel, James Coplein, et al. represent those who believe that the semimystical aspects of Alexander represent the true essence of his message. For them, a pattern ”and even more important, a pattern language ”is quite different from what has been popularized as a pattern. The popular GoF view
Patterns for object thinkers are mental shortcuts or cues that direct thinking along known paths and facilitate the discovery of a problem solution. Of course, this means that the patterns themselves must be consistent with object thinking philosophy and principles, or their use will be counterproductive.
Patterns most useful to object thinkers should be derived from the problem domain, just as objects are. They should facilitate thinking about coordination and scripting of objects or about useful ways of assembling objects into components or applications. They could be considered Alexandrian patterns. Few of the patterns (about 6 of the 23) presented in the GoF book satisfy this demand. Martin Fowler s book on Analysis Patterns presents examples derived from a domain and is much closer to Alexander s intent than the GoF book.
Patterns that reflect the solution space are useful to the object thinker but in a very different way. If you have thought about and designed an object solution to a problem, you must still implement your solution using a programming language. Not all languages directly support object ideas, and many languages contradict object principles. If you must use such a nonoptimal language, design patterns of the sort in the GoF book provide insights that can minimize the distortion caused by the implementation language.
GoF patterns might better be called implementation patterns than design (or thinking) patterns. Other types of implementation patterns would include the coding standards that constitute one of the twelve XP practices. In particular, programming idiom or style provides a powerful pattern for implementation as well as for communication among developers. Apple s style guide for Macintosh GUIs, Kernigan and Ritchie s style for the C programming language, and Kent Beck s Smalltalk Best Practice Patterns are all examples of programmer idiom.
[2]
There s the joke about the large, leather-clad, menacing biker accompanied by his equally large and fierce Doberman who enters an elevator car occupied by a middle-class couple. When the