Prev: Critique of Robert C. Martin's "Agile Principles, Patterns, and Practices"
Next: "Modern" Software Framework?
From: Daniel T. on 1 Aug 2007 15:56 In article <f8qecv$37t$1(a)aioe.org>, "S Perryman" <a(a)a.net> wrote: > "Daniel T." <daniel_t(a)earthlink.net> wrote: > > > In article <f8q0tl$q07$1(a)aioe.org>, "S Perryman" <a(a)a.net> wrote: > > DT> (2) Such preconditions often are a repeat of the invariant of the class. > > > > I have never seen a pre-condition that is a 'repeat' of an invariant. > > > Feel free to give an example. > > > > class RANGE > > feature > > low : INTEGER > > high : INTEGER > > > > setLow( value : INTEGER ) > > require value < high > > ensure low = value > > high = old high > > end > > > > invariant > > low < high > > end > > > > My Eiffel is a bit rusty, but notice how "value < high" is basically the > > same as "low < high" because "setLow" assures the equivalence between > > "low" and "value" > > (value < SELF.high) is not the same condition as (SELF.low < SELF.high) . > > Both use a common operation ( < ) , and parameter (SELF.high) . > But neither of the above makes one condition "repeat" the other (you need > value = SELF.low in order to achieve that) . Ah, but the ensure is "value = SELF.low" . That is what I am talking about when I say that the precondition repeats the invariant. The terminology may be week, but the code makes the point, I think.
From: S Perryman on 2 Aug 2007 04:14 "Daniel T." <daniel_t(a)earthlink.net> wrote in message news:daniel_t-E87AFE.15562201082007(a)news.west.earthlink.net... > In article <f8qecv$37t$1(a)aioe.org>, "S Perryman" <a(a)a.net> wrote: DT> class RANGE DT> feature DT> low : INTEGER DT> high : INTEGER DT> setLow( value : INTEGER ) DT> require value < high DT> ensure low = value DT> high = old high DT> end DT> invariant DT> low < high DT> end DT> My Eiffel is a bit rusty, but notice how "value < high" is basically the DT> same as "low < high" because "setLow" assures the equivalence between DT> "low" and "value" >> (value < SELF.high) is not the same condition as (SELF.low < SELF.high) . >> Both use a common operation ( < ) , and parameter (SELF.high) . >> But neither of the above makes one condition "repeat" the other (you need >> value = SELF.low in order to achieve that) . > Ah, but the ensure is "value = SELF.low" . That is what I am talking > about when I say that the precondition repeats the invariant. The "ensure" is the *post-condition* , not the pre-condition. The post-condition definitely "repeats" a term found in the pre-condition : the *invariant* . >The terminology may be week, but the code makes the point, I think. I think not (for either the terms used or the point being claimed) . All I can see is a common condition C(x,y) which captures the essence of numeric ranges. No problem with that. C is used accordingly to define the invariant/pre-conditions of the Range type. The *parameters* given to each use of C depend on the context (which operation etc) . But as I stated, unless the *values* of the parameters given to C by the pre/ invariant conditions are *the same* at the point of evaluating the pre- condition, there is no "repetition" (ironically if this was the case, setLow etc are effectively no-ops) . OTOH, factoring a common condition C and then using it with different parameters at different places is not repetition, merely good practice. Regards, Steven Perryman
From: H. S. Lahman on 2 Aug 2007 12:22 Responding to Carter... > In Bertrand Meyers book "Object oriented Software Construction" 2nd Ed he > says section $11.8....(Discussing class invariants) > > "The precondition of a routine may involve the _initial state_ and the > arguments." > > (Emphasis mine) > > I would argue that is a mistake. Since if the precondition involves the > state of the object, it implies the calling routine must know the state of > the object. I think you are reading too much in the Meyer quote. Note the 'may'. In the OO paradigm knowledge (state variable attributes) and behavior are separated and treated quite differently. Any state variable that is accessible through a relationship path can be accessed by a method so /all/ such state variables are potentially part of the method's input alphabet as far as DbC is concerned. All Meyer is saying is that there is an implicit relationship path (via 'this') to the object's own state data. Since knowledge is separate from behavior, changing the state values is done separately from invoking behaviors. (When a method sets state variable, it has to invoke a synchronous accessor.) So what Meyer is saying is that if the object's own data is accessed, then there is a precondition on its state that may have to be satisfied by invoking an object synchronous knowledge accessor before the behavior method is invoked. That would be true no matter who owned the data being accessed by the method. [Note that for concurrent and/or asynchronous processing this separation is crucial for efficient management of data integrity at the method level. One has to ensure that no one updates the relevant state variables while the method is executing. That is <relatively> easy to do if one can count on the fact that all state variables are accessed synchronously through dedicated accessors (when combined with peer-to-peer collaboration). That's because one can figure out syntactically what state variables are being accessed and use that to ensure proper blocking. Corollary: it doesn't matter who owns the state data; one just has to ensure it is timely (DbC precondition) and isn't being changed as the behavior executes.] ************* There is nothing wrong with me that could not be cured by a capful of Drano. H. S. Lahman hsl(a)pathfindermda.com Pathfinder Solutions http://www.pathfindermda.com blog: http://pathfinderpeople.blogs.com/hslahman "Model-Based Translation: The Next Step in Agile Development". Email info(a)pathfindermda.com for your copy. Pathfinder is hiring: http://www.pathfindermda.com/about_us/careers_pos3.php. (888)OOA-PATH
From: Miguel Oliveira e Silva on 14 Aug 2007 14:27 John Carter wrote: > In Bertrand Meyers book "Object oriented Software Construction" 2nd Ed he > says section $11.8....(Discussing class invariants) > > "The precondition of a routine may involve the _initial state_ and the > arguments." > > (Emphasis mine) > > I would argue that is a mistake. No it is not. > Since if the precondition involves the > state of the object, it implies the calling routine must know the state of > the object. Of course (if that is what is required by the contract expressed by the precondition). > This tends to be a violation of the "tell, don't ask" formulation of the > Law of Demeter. > For example... > // In the client code... > if( a.isSomePredicate()) > a.doThis(); > else > a.doThat(); > end > // In the object code... > > void A::dothis() > { > assert_precondition( isSomePredicate()); > .... > } > > instead of the better pattern of... > > // In client code... > a.doTheRightThing(); > > // In the object code... > > class A { > private: > void doThis(); > void doThat(); > bool isSomePredicate(); > > public: > void dotheRightThing() { > if( a.isSomePredicate()) > a.doThis(); > else > a.doThat(); > } > > }; Why better [all the times]? Lets look at a more concrete example: class STACK[T] feature push( v: T) is ... end; pop: T is require not is_empty do ... end; is_empty: BOOLEAN is ... end: end -- STACK[T] (In this case) It is definitely the clients responsibility to send the pop message to a non-empty STACK object. This object has no way of knowing what to do (other then, of course, raise an exception) inside a pop operation in an empty STACK. > Consider a typical example... > > while( stream.notEmpty?()) { > value = stream.getNext(); > // do stuff... > } > > This tends is messy and tends to be prone to errors arise out of the > predicate changing value between the notEmpty? call and the getNext() That is a concurrency problem (not a precondition limitation/problem). There are several approaches (within the Eiffel community) to this problem. Take a look at CORDIE06's proceedings: http://www.artist-embedded.org/artist/Proceedings.html And also this (draft) article: http://www.ieeta.pt/~mos/pubs/inter-object-reservation-2006-draft.pdf > (...) > Question 1 to the group: > > Can you think of a case where the precondition _must_ involve the state? Yes (lots of them). Preconditions are assertions that clients are required to ensure. If a service only makes sense to be used in particular states of the object (partial function), then such contract should be clearly expressed in its precondition (as in the pop operation of a stack). > Question 2 to the group: > > Can you think of a case where the code is improved by allowing > the precondition to depend on the state? Yes (whenever there is a partial function on the object's state involved). Object-oriented languages and techniques are an imperative approach to programming. Explicit state is a required (a better word would be: desired) part of it. > Thank you, Best regards, -miguel -- Miguel Oliveira e Silva
First
|
Prev
|
Pages: 1 2 Prev: Critique of Robert C. Martin's "Agile Principles, Patterns, and Practices" Next: "Modern" Software Framework? |