Re: Client/Service relationships & Flow of Requirements.
- From: "H. S. Lahman" <h.lahman@xxxxxxxxxxx>
- Date: Wed, 31 Jan 2007 17:22:51 GMT
Responding to Daniel T....
I think the disagreement lies in why one wants the mindset that separates message and method and makes messages announcements. Doing so has no intrinsic benefits. The benefits lie in the developer being forced to do other things properly...
The basic assumption in the "client owns the interface" principle is that the client needs the service to perform some action on its behalf. Obviously the client must be able to inform the service when to perform that action, so the client gets to add methods to the interface describing the services it needs. However, when messages are used to inform, rather than compel, the onus is on the message sender to do the informing.
The predator/prey example can serve to illustrate what I mean:
The following is designed to compel Prey objects to do something:
class Prey:
def runFrom( predator ):
require: predator < 100 yards from prey
ensure: predator > 100 yards from prey
Note that the DbC precondition assertion is implemented in the Prey but it is really checking the correctness of the Predator software -- the Predator has no business sending the message unless the condition {predator < 100 yards from prey} prevails. So the DbC precondition is just validating a requirement that has already been allocated to Predator was implemented correctly.
Similarly, the Prey has a responsibility to react to the message, which is described by the DbC postcondition for the Prey's response to the message. That postcondition just expresses the requirements allocated to the Prey behavior.
So...
Whatever code sends the "runFrom" message to prey objects, it expects a particular result, it is specifically sending the message so that the prey will move away from the predator. (I.E., to cause the state to change such that the predator and prey are more than 100 yards away from each-other.) There is no requirement on the client to send the "runFrom" message if the client doesn't want the prey object to move.
However, if the message is designed to inform rather than compel:
class Prey:
def predatorWithin100yards( predator ):
require: n/a
ensure: n/a
Now, the contract (which can't be stated properly in either the require or ensure clause) is that anytime a predator is within 100 yards of the prey object, it shall be informed of that fact. The onus is on the client to do the right thing. The Prey object need not do anything at all in response to the message.
I can't buy your conclusion. The message announces that a particular condition exists (i.e., predator < 100 yards from prey). That condition is exactly the same as the first case, so I think the DbC precondition is the same. (The name of the message is misleading; it could have been a predatorSneakedUp announcement and the precondition would still hold.)
Similarly, the Prey still has the same response to receiving that announcement (i.e., to move such that predator > 100 yards from prey). So I think exactly the same DbC postcondition applies here.
The only difference I see in the two examples is that the name of the message better expresses the I'm Done vs. Do This mindset that one needs to design the Predator. That is, the reason one separates message from method and thinks of messages as announcements in the OOA/D is not because of any intrinsic difference in the way responsibilities are allocated. It just prevents one from creating a dependency in the message sender on what the specific response is.
[At OOP time the message is going to be the method signature and the Predator will have to know the type of Prey. So all of that conceptual decoupling will have been apparently wasted because of physical coupling in the 3GLs. But from a design viewpoint it will not have been wasted because the Predator will be constructed so that the physical coupling of the 3GL is benign.]
----
Now let me get back to the opening statement about the client owning the interface. It is true that one designs the interface encapsulating the service semantics to the needs of the client. IOW, the client determines the /way/ in which the semantics is accessed. So in a large project with different teams working on different subsystems, the teams will typically negotiate the interface that the service subsystem provides.
But that is usually pretty cosmetic once one settles on the right level of abstraction. And the level of abstraction will usually be determined by the invariants of the service semantics _as seen by the client_. Similarly, large scale reuse also depends upon the interface being expressed in terms of service semantic invariants.
My point here is that I think some of you issues lie in interface design practice. I think the issues around announcement messages are largely independent of that. The Predator has changed the condition of the application by creeping up on the Prey. That condition is {predator < 100 yards from prey}. So the Predator (or some bystander) announces that the condition prevails with a message. The Prey cares about that condition prevailing so the announcement is routed to it. When the Prey receives it, the Prey responds by executing a behavior responsibility. The postcondition of that responsibility is {predator > 100 yards away from prey}. All that is independent of the syntax of the interface that describes the actual message.
OTOH, the crucial thing is that in the OOA/D the Predator doesn't even know where the message is going when the announcement of the prevailing condition is made. That precludes designing the Predator behavior that detects the condition change from depending in any way on what the Prey does. So if the Predator is going to respond to the Prey's response (e.g., chasing the dodging Prey), that will have to be handled by different Predator behavior responsibilities that responds to changes in conditions that the Prey announces. IOW, one is forced to make Predator behavior responsibilities cohesive and logically indivisible (and probably Prey's as well).
- - - - -
If I add a compel type method to the Prey class, the client need not call it unless the client wants the prey to do what the method compels it to do.
If I add an inform type method to the Prey class, the client must be modified to call it or the Prey objects won't work right.
- - - - -
It is obvious (at least to me) why the "inform" interface is better, the prey is making its own decisions as to what it will do in response to the predators position (it may decide to charge rather than run for example.) But the prey can't do the right thing, if it isn't informed when the condition holds.
This also shows how DbC is an inherently procedural methodology. Well constructed OO methods have no ensure clause.
I have to disagree with that conclusion also. I suppose one could argue that putting DbC precondition assertions in the receiver is a procedural view, but I think that is a stretch. The postcondition of the message sending method must match those preconditions (albeit perhaps as a superset). That postcondition is driven by the requirements that have already been allocated to the message sending object during problem space abstraction, not the message receiver. The DbC precondition assertion is just validating that the requirements were allocated properly in the outside world. IOW, the developer is still responsible for ensuring the message sender was properly constructed. I don't that as a uniquely procedural view.
*************
There is nothing wrong with me that could
not be cured by a capful of Drano.
H. S. Lahman
hsl@xxxxxxxxxxxxxxxxx
Pathfinder Solutions
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
"Model-Based Translation: The Next Step in Agile Development". Email
info@xxxxxxxxxxxxxxxxx for your copy.
Pathfinder is hiring: http://www.pathfindermda.com/about_us/careers_pos3.php.
(888)OOA-PATH
.
- References:
- Client/Service relationships & Flow of Requirements.
- From: John Carter
- Re: Client/Service relationships & Flow of Requirements.
- From: Daniel T.
- Re: Client/Service relationships & Flow of Requirements.
- From: H. S. Lahman
- Re: Client/Service relationships & Flow of Requirements.
- From: Daniel T.
- Client/Service relationships & Flow of Requirements.
- Prev by Date: Re: Pushing Hot Buttons - Object State Machines === Threads with goto's
- Next by Date: Re: Critique of Robert C. Martin's "Agile Principles, Patterns, and Practices"
- Previous by thread: Re: Client/Service relationships & Flow of Requirements.
- Next by thread: Re: Client/Service relationships & Flow of Requirements.
- Index(es):