For those of you who have read POODR, it seems to me that the book articulates two levels of context independence, the first one being the level articulated in GOOS, and which is achieved by using third-party-connect (dependency injection), and the second one being achieved by (in what superficially at first might appear a reversal of LoD) getting collaborations to shift from A telling
B HOW to bring about what A wants, to A asking B WHAT it wants, and trusting B to do the right thing to bring it about.
Here are a couple of extracts on context independence from GOOS:
"A system is easier to change if its objects are context-independent; that is, if each object has no built-in knowledge about the system in which it executes. This allows us to take units of behavior (objects) and apply them in new situations. To be context-independent, whatever an object needs to know about the larger environment it’s running in must be passed in. Those relationships might be “permanent” (passed in on construction) or “transient” (passed in to the method that needs them).
In this “paternalistic” approach, each object is told just enough to do its job and wrapped up in an abstraction that matches its vocabulary. Eventually, the chain of objects reaches a process boundary, which is where the system will find external details such as host names, ports, and user interface events."
"The effect of the “context independence” rule on a system of objects is to make their relationships explicit, defined separately from the objects themselves. First, this simplifies the objects, since they don’t need to manage their own relationships. Second, this simplifies managing the relationships, since objects at the same scale are often created and composed together in the same places, usually in mapping-layer factory objects.
Context independence guides us towards coherent objects that can be applied in different contexts, and towards systems that we can change by reconfiguring how their objects are composed."
POODR also values context independence:
"The context that an object expects has a direct effect on how difficult it is to reuse. Objects that have a simple context are easy to use and easy to test; they expect few things from their surroundings. Objects that have a complicated context are hard to use and hard to test; they require complicated setup before they can do anything. The best possible situation is for an object to be completely independent of its context."
But what POODR does next is distinguish between a first level of context independence, achieved by using dependency injection, and a further
level:
"An object that could collaborate with others without knowing who they are or what they do could be reused in novel and unanticipated ways. You already know the technique for collaborating with others without knowing who they are—dependency injection. The NEW PROBLEM here is for Trip to invoke the correct behavior from Mechanic without knowing what Mechanic does. Trip wants to collaborate with Mechanic while maintaining context independence."
Before we look at a few more extracts from POODR to show how Metz solves the 'NEW PROBLEM', and especially for the benefit of those who haven't read the book, or who won't want to go into any more detail, Metz's solution is to shift from telling a collaborator how to behave, to asking a collaborator for what one wants and trusting the collaborator to deliver:
"This blind trust is a keystone of object-oriented design. It allows objects to collaborate without binding themselves to context and is necessary in any application that expects to grow and change.
...
When messages are trusting and ask for what the sender wants instead of telling the receiver how to behave, objects naturally evolve public interfaces that are flexible and reusable in novel and unexpected ways."
Met'z solution is the final of three approaches she explores, which she says "represent a movement towards increasingly object-oriented code and as such they mirror the stages of development of the novice designer"
"If objects were human and could describe their own relationships", she says that in the three approaches the objects would describe their relationships as follows:
- “I know what I want and I know how you do it;”
- “I know what I want and I know what you do”
- “I know what I want and I trust you to do your part.”
For those who have read the book and are interested, let me restate 'THE NEW PROBLEM' before we look at a couple more extracts:
"The NEW PROBLEM here is for Trip to invoke the correct behavior from Mechanic without knowing what Mechanic does. Trip wants to collaborate with Mechanic while maintaining context independence."
Here is how POODR elaborates the 'NEW PROBLEM'
"At first glance this seems impossible. Trips have bicycles, bicycles must be prepared, and mechanics prepare bicycles. Having Trip ask Mechanic to prepare a Bicycle
seems inevitable. However, it is not. The solution to this problem lies in the distinction between what and how, and arriving at a solution requires concentrating on what Trip wants. What Trip wants is to be prepared. The knowledge that it must be prepared is completely and legitimately within the realm of Trip’s responsibilities. However, the fact that bicycles need to be prepared may belong to the province of Mechanic. The need for bicycle preparation is more how a Trip gets prepared than what a Trip wants."
POODR then shows an activity diagram that solves the problem and says:
"In this example, Trip merely tells Mechanic what it wants, that is, to be prepared, and passes itself along as an argument. In this sequence diagram, Trip knows nothing about Mechanic but still manages to collaborate with it to get bicycles ready. Trip tells Mechanic what it wants, passes self along as an argument, and Mechanic immediately calls back to Trip to get the list of the Bicycles that need preparing. All of the knowledge about how mechanics prepare trips is now isolated inside of Mechanic and the context of Trip has been reduced. Both of the objects are now easier to change, to test, and to reuse."
Philip