From: H. S. Lahman on 20 Aug 2006 13:26 Responding to Ulf... >>But the object's state does not affect substitutability. > > > I beg to differ. But slowly: > > (1) To me: Object's state includes the current value of its attributes. > There may be more aspects (like modeled in the state machine), but only > the attribute aspects matters in my argument. > [Sidenote: Note that the far link-end(s) of an object's links may be > mapped to attribute(s) of that object.] > > Do you agree? I agree with (1) but I am not sure what you mean by the parenthetical comment. > > (2) Obviously: Depending on the current attribute values, an object's > operations' semantics may be specified and/or implemented by a method. > In particular, the result of an operation/method may depend on the > current attribute values. IOW operation results depend on object state. > > (3) Liskov and Wing suggest in a section about history properties: > Substitutability in their definition (LSP-subsititutability) is > affected -- even if the semantics (or implementation, as you like) of a > superclass's operation is NOT overridden! -- if new operations in the > subclass change attributes inherited from the superclass in a way that > operations of the superclass never did. However, as I have already pointed out, in an OO context there is only one specification of the responsibility. More to the point here, the superclass does not (more properly, should not) have concrete implementations that are overridden in subclasses. In addition, each behavior is represented as a unique property, so "new" behaviors are orthogonal to existing properties. IOW, there are no superclass operations to modify in an OO context. > > Do you believe my report about what is in Liskov&Wing's paper? Yes. > Do you agree with Liskov&Wing's suggestion? Only in a very limited sense in an OO context. As I indicated in the other message, LSP applies to knowledge responsibilities as well as behavior responsibilities. So the definition of knowledge attributes must be consistent. One can't define Rectangle with attributes for majorSideLength and minorSideLength and then derive a Square subclass that only defines sideLength. Beyond that, in addition to my response to (3), OO methods are very pure because of methodological constraints on the way they are constructed. Since they are intrinsic, self-contained, and logically indivisible, one can express their specification purely in terms of a transformation of input values to output values. It is that contractual definition that must be honored for all implementations to ensure substitutability. So if method A modifies attribute Z, then attribute Z is just an input/output value in the specification of method A's responsibility. The fact that Z happens to be a knowledge property of the same object is serendipity. The old value could just as well have in a stimulus event's data packet and the new value in an output event's data packet. That is, the semantics of Z don't matter to the specification of A; only the transformation of the value matters. Thus the values themselves cannot affect substitutability adversely because they are already part of the specification of the responsibility transformation that provides the criterion for substitutability. >>... I was >>responding to your suggestion that substitutability could somehow be >>affected by the sequence of (history of) messages an object receives: >>... > > > I want to reaffirm this. See B above for a rephrasing. I don't know how > otherwise to help you understand loss LSP-substitutability caused by > non-preservation of history properties. Again, the problem here is OO context vs. the more generic 3GL context where type systems were developed. The OOA/D model for knowledge access is synchronous but the model for behavior access is asynchronous. (That's because the asynchronous model is the most general so it can be implemented in either a synchronous or asynchronous computing environment.) The corollary is that because of the postulated arbitrary delay in asynchronous processing between when a message is sent and when it is responded to, one must design the application to be independent of dependencies between messages. So such history can't be relevant in a well-formed OO application because of the methodological constraints the OO paradigm already places on construction. > > >><snip> >> >>I think state variable values are a red herring. The values change the >>results of executing the responsibility based on dynamic context, not >>what the responsibility /is/. > > > Certainly. > > >>In the example above, specifying a responsibility to sort a list of >>integers in ascending order does not depend in any way on what the >>values are. ... > > > "not in any way"? You can you specify that the list is sorted in the > end without looking at the values in the list? Of course. All you need to know is the nature of the values (integers, text strings, etc.) and a mathematical definition of greater, equal to, or less than appropriate for the nature the values. You don't need to know anything about the individual values. >>... >> >>>>Does what a >>>>behavior does depend in any way on what some other behavior does? >>> >>>Sounds odd to talk of a behavior _doing_ sth. In normal seach the >>>behavior _is_ the doing. Do you mean a behavior = a method? Maybe we >>>should distinguish actual behavior (the doing) from behavior = method >>>(the definition/implementation of what to do)? >> >>In the OO paradigm a method implements a behavior responsibility. > > > I thought in the OO paradigm one says a method implements an operation > (or maybe even in some indirect sense implements a message). UML has a penchant for creating subclassifications. So Messages are called Signals, Call Events, and a bunch of other things. Behavior responsibilities are called Operations while knowledge responsibilities are called Attributes. But Methods are called methods. A Message triggers an Operation and the Operation is implemented in a Method. >>The responsibility defines what the method should do. > > > Hm. That seems different to "operation". One wouldn't say > The operation defines what the method should do (or would one?) > > >>IOW, responsibility = What; method = How. > > > A
From: H. S. Lahman on 20 Aug 2006 14:30 Responding to Ulf... >>>IMHO, a class system is - on the right level of abstraction - a type >>>system in the second sense. > > > IOW, a class system is a system of types. That wasn't my quote. A class system is definitely not a system of types. As I pointed out already, the only place types appear at all in OOA/D is in attribute ADTs. >>[Class systems and type systems] >>are obviously unambiguously mappable because they share property >>sets, but I don't think they are the same thing. Class systems are >>about member identity and classification while type systems are about >>interfaces and access. > > > But types are about classification! - Classification of "values" in > some sense. Sure. But it is a classification based on access, not identity and set membership. > Cf. Cardelli & Wegner's "On understanding types, data abstraction and > polymorphism". > Hence a system-of-types (type system) is about classification. Types > talking about interfaces is just a means for classification where the > "values" are objects. Isn't the same done in class system's where > objects are classified (among others!) based on their message > interface? > > Last time I checked, UML included access specification for members as > part of the class model. Do you mean they can be in the class model but > not in the class system? Then I would seem to need from you a > definition what you mean by a class system. Those are technically Operations. As I explained in the other message, they map to responsibilities. Actually UML provides a separate model element, Interface, from the Class to describe how the class members are accessed. It is that model element that maps to a type at the 3GL level, not the Class in the Class Model. IOW, types are about what messages the object in hand can process while classes are about which objects one can talk to. >>From type theory I can tell you that access specifications are only > relevant in the system-of-typing-rules (type system 1st sense) for > determining which accesses are type correct. They are usually not > represented in the system-of-types (type system 2nd sense) - but maybe > they better should? > > So maybe after all you are right and here is a difference between class > systems and type systems (in the sense of system-of-types)? - just that > it is the other way around than you thought :) > > Could you elaborate in what sense class systems "are about member > identity"? Classes are pure sets. The crucial perspective, though, is that one has an identifiable entity in hand and wants to determine who can talk to it. Thus in OOA/D identity is crucial because it determines who participates in collaborations. Relationships, in turn, provide the constraints on who may participate. Those constraints are based on set membership through classes because classes provide the infrastructure for object relationships. So the class system provides a convenient way to organize sets of identifiable entities so that access over relationship paths is constrained. (One then uses relationship instantiation to ensure that This entity can only talk to That subset of entities in another class.) In contrast, the issues of consistent access that so dominate type systems are quite irrelevant to OOA/D because the mechanics of collaboration have been highly abstracted. The client object generates a message of {message ID, data packet} and addresses it to a particular member reached by navigating relationships. The client neither knows nor cares about the details of access. But it cares a whole lot that the message goes to the right entity. For example, in an abstract action language one might have something like: ref = this -> R1 -> R2 GENERATE E1 ref attr1, attr2 The first line navigates <presumably 1:1 here> relationships, R1 and R2, to get to an object. The second line generates a message with a message ID of E1 and some attribute values for the data packet. The important thing to note here is that to specify these activities in the client's method I don't even have to know what class the receiving object belongs to, much less what responsibility will be invoked or how it will be accessed. Those concerns are only critical at the OOP level where one must put up with the vagaries of 3GLs, which type systems bring order to. IOW, to collaborate at the OOA/D level I only need to identify the receiver of my message. I prune the candidates for collaboration through the constraints of relationship instantiation. That, in turn, is enabled by organizing identifiable entities into sets in a class system. >>For example, one cannot deal with class systems >>without talking explicitly about sets ... while one can >>easily talk about types systems without mentioning sets at all. > > > If I claim "Carnivore is a specialization of Animal" - where is there > the "explicit" talk about sets? Or does this not fall under "dealing" > with a class system? Carnivore is a subset of Animal with unique, specialized responsibilities. As I pointed out already, an OO generalization in UML is nothing more than a Venn Diagram in tree form. ************* 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: ulf on 21 Aug 2006 19:16 H. S. Lahman wrote: > > ... > > a. Responsibilities *are* (basic) properties > > b. Properties are *defined* in terms of responsibilities (for > > knowledge/behavior) > > ----------------------- > > c. => Responsibilities are defined in terms of responsibilities ... ? > > Not quite. The point was that in the OO paradigm only certain kinds of > responsibilities (i.e., responsibility for knowing something or > responsibility for doing something) can be object properties. For > example, there is no direct way to abstract the notion of 'purpose' in > an object as a responsibility. OK. No more discussion here. Thanks. > >>IOW, objects are defined in terms of What > >>they should know and/or What they should be able to do. > > > > Of course. Or as I like to say it: > > The dual nature of the object abstraction = data abstraction + > > behavioral abstraction. > > This is a common problem for OO novices and one of the main reasons the > OO paradigm defines properties in terms of responsibilities is to avoid > this sort of correlation to hardware computational models. Notions like > 'behavior' and 'data' carry a lot of baggage in the computing space. Yes. One can make the same distinction alternatively by introducing a fresh term "responsibility", or one can emphasize the conceptual similarity by qualifying the computing space-level concepts with the term "concrete" and the others with the term "abstract" [so that eventually talk of abstract data/behavior will push talk of concrete data/behavior aside and become the normal understanding of the terms "data" and "behavior" ;) ] > The responsibility for knowing something does not imply a data store > (e.g., the object can satisfy its responsibility by computing a value > whenever asked). Yes. The great thing about data *abstraction* aka. abstract data is that it *behaves* like data without the need to always store it as concrete data. In abstract data, all data is reduced to behavior (one of the first to point this out was John C Reynolds 1975). Maybe "knowledge abstraction" would be an even better term for contrast. I just sticked to the established term here. Also "knowledge" or [responsibility for] "knowing" has an air of AI to me, which I would prefer not to evoke here. > Nor does a responsibility for doing something imply > the execution of set of computations (e.g., the object can satisfy its > responsibility for doing something by simply sending a message). ... Yes. The great thing about behavioral abstraction (aka. procedural abstraction or [communicating] process abstraction, but even for me this smells too lowlevel, too procedural paradigm in an OO context) is that it becomes irrelevant where and how the behavior is done, just its external effects count. Since we talk about terminology, let me say I am not happy with "responsibility" either: Saying an object has the "responsibility for knowing/doing sth." does not include in its meaning whether the object actually does know/do it. This may be good for expressing requirements for systems still to be built, but does not fit as well to describe existing systems/classes/frameworks... Whereas when I say an object has the abstract data (property) X or abstract behavior (property) X then I express that it *does* know/do X (and say nothing about how it does this). > > ... > > Just to verify: From the following choices yours is (a), right? > > > > a. There can be no two places/sets where the same > > responsibility/property is defined. > > b. There can be two places/sets but the definitions cannot be > > different. > > ... The OO tree for for generalization just > makes placing the definition in one place convenient. IOW, it is a > shorthand to avoid redundant specification and make is easier to > recognize the proper level of access to the generalization. OK. > > c. There can be two places/sets, the definitions can be different, > > but not in a conflicting manner. > > > > Whereas I was considering choice c. > > Does anyone reading this know what the UML 2 spec is saying here? > > That probably isn't relevant, though I suspect UML is in agreement. UML > 2 is designed to serve quite different masters than just OO development. > So one really has to look at the formally defined MDA profiles for OO > development that provide additional constraints. MDA profiles - I should check these out. Thanks. > >... > > The OO generalization relation is about providing specialized > specifications for what particular members of the root superclass are. > However, that is a quite different thing from refining the specification > of individual properties. OO generalization provides specialization by > /adding/ properties, not modifying those that are already defined. > > [Of course providing a different implementation is a form of redefining > the property. ... Hm. How does fit the reduction of underspecification fit into this scheme? Example (it may be a boring foundational computational example, but certainly has specific correlates in many problem domains): 1. A List class has a sorting responsibility/property for sorting its elements according to some order, eg. lexicographic sorting of telephonebook entries by their names. This leaves open how to order (what the ordering responsibility is) for entries with the same name. 2. In a specialization of the List class I could REFINE the sorting responsibility/property by additionally specifying that entries with the same should keep their orginal order. Or maybe would you prefer to say ADD a new responsibility (basic object property) to the sorting property (now a complex property defined in terms of two responsibilities, or maybe more - I'm not sure yet how to count them). This has nothing to do different algorithms (ie. solutions/implementations/realizations) for the same sorting problem/requirement. It is a refinement/strengthening of the sorting problem/requirement. [Of course this refinement reduces the choice of algorithms solving it.] Can you in this case still say "the semantics of the responsibility is exactly the same from the perspective of an external client"? > Alas, the OOPLs are a poor way of learning about the OO paradigm ... Agreed. > > "Implementation/realization of a responsibility/property" (for > > knowing/doing) I understand. What opposed to this is an "imple
From: Rick Elbers on 22 Aug 2006 09:28 Ulf, You touch somewhere a terminological issue which I would discuss, skipping the main line of the discussion with Lahman. > >Since we talk about terminology, let me say I am not happy with >"responsibility" either: Saying an object has the "responsibility for >knowing/doing sth." does not include in its meaning whether the object >actually does know/do it. This may be good for expressing requirements >for systems still to be built, but does not fit as well to describe >existing systems/classes/frameworks... >Whereas when I say an object has the abstract data (property) X or >abstract behavior (property) X then I express that it *does* know/do X >(and say nothing about how it does this). > This is interesting. I am not native english speaker, but I think I understand that you implied that: Sayiing "an object has some responsibility to do something" has a much richer meaning then: Saying "an object actually does something" Am I right so far ? In my experience in design talking about responsibilities drives the design, which is indeed much more then that it only establishes object properties or actual behaviors. It helps filling in colloborations and gaps between objects too. In my experience in implementation we tend to be reduced to non-thinking problem solvers. What works now is what we are looking for. All too often we even lose the carefully balanced ideas of design about responsibilities and objects, and we only see the functional machine. Adding or changing or skipping a method or property, no big deal. In that effort we loose every gain of oo in my view, and we just code away procedural code in objects. This is why my main belief is that the best thing you can do for software engineering is to keep the non-technical talk about software alive up to the last nifty detail. Therefore the "semi-exact" terminology of "responsibility" provokes the exact right smell for me. It beats obsessive behavior to talk in less strict terms imho. > >Ulf Schnemann Rick
From: H. S. Lahman on 22 Aug 2006 12:38
Responding to Ulf... > Since we talk about terminology, let me say I am not happy with > "responsibility" either: Saying an object has the "responsibility for > knowing/doing sth." does not include in its meaning whether the object > actually does know/do it. This may be good for expressing requirements > for systems still to be built, but does not fit as well to describe > existing systems/classes/frameworks... I don't see that as an inconsistency. The responsibility is an obligation the object has. So it must actually know/do it or it will fail its obligation. IOW, it is the developer's responsibility to ensure the object actually fulfills its obligations and all clients assume those obligations are fulfilled at run time. >>> c. There can be two places/sets, the definitions can be different, >>>but not in a conflicting manner. >>> >>>Whereas I was considering choice c. >>>Does anyone reading this know what the UML 2 spec is saying here? >> >>That probably isn't relevant, though I suspect UML is in agreement. UML >>2 is designed to serve quite different masters than just OO development. >> So one really has to look at the formally defined MDA profiles for OO >>development that provide additional constraints. > > > MDA profiles - I should check these out. Thanks. The only formal one I know of right now is the one defined for translation in "Executable UML" by Mellor and Balcer. (But I don't doubt there are other formal profiles by now.) Most OOA/D methodologies define an informal or de facto MDA profile. UML 2 and MDA don't really change existing approaches, they just broaden the scope through addition. > > >>>... >> >>The OO generalization relation is about providing specialized >>specifications for what particular members of the root superclass are. >>However, that is a quite different thing from refining the specification >>of individual properties. OO generalization provides specialization by >>/adding/ properties, not modifying those that are already defined. >> >>[Of course providing a different implementation is a form of redefining >>the property. ... > > > Hm. How does fit the reduction of underspecification fit into this > scheme? > Example (it may be a boring foundational computational example, but > certainly has specific correlates in many problem domains): > > 1. A List class has a sorting responsibility/property for sorting its > elements according to some order, eg. lexicographic sorting of > telephonebook entries by their names. > This leaves open how to order (what the ordering responsibility is) for > entries with the same name. > > 2. In a specialization of the List class I could REFINE the sorting > responsibility/property by additionally specifying that entries with > the same should keep their orginal order. Or maybe would you prefer to > say ADD a new responsibility (basic object property) to the sorting > property (now a complex property defined in terms of two > responsibilities, or maybe more - I'm not sure yet how to count them). You are correct, I oversimplified. One can also provide specialization by constraining a general specification. One can define the List superclass ordering in a generic fashion where one can implement with or without preserving original order. One can then provide subclasses that choose one or the other. That may or may not be important to clients. To that extent, in our earlier discussion about whether subclasses modify/override superclass specifications, you were correct that they do. My hang-up was about modify/override. I think of those as different activities than constraining something. That is, in my view modify/override implies that one changes the nature of something while constraining it does not. >>>"Implementation/realization of a responsibility/property" (for >>>knowing/doing) I understand. What opposed to this is an "implementation >>>of a responsibility semantics"? ... > > > I would appreciate if you could enlighten me. Sorry, I don't understand the question. > > >>>... >>> >>> >>>>... But in both cases the semantics of the >>>>responsibility is exactly the same from the perspective of an external >>>>client for each implementation pair. >>> >>>... Did you mean: >>> >>> But in both cases the semantics of the *implementation* of the >>>responsibility is exactly the same from the perspective of an external >>>client ... >> >>That's another way of saying it, yes. But the key issue is that the >>client only knows about the responsibility, not the implementations of >>it that are hidden in an OO context. > > > Agreed with the issue and aggreed that it is the key issue. But while > that key issue is obvious to me, I needed something else as key to > understanding your expression: Namely the clarification that you were > not talking about the semantics of the responsibility as it was defined > in some higher level class, but the actual semantics which the > responsibility has in a particular concrete object implementing that > class. I only agree with that clarification in the specific context of a subclass constraining a more general superclass responsibility. And then I see the specification as fundamentally the same; it is just qualified in the subclass. That sort of specialization is actually a pretty unusual situation and most specializations are created by defining properties that are not shared by sibling subclasses. In those situations there is only one definition of the added properties. <aside> Note that your List example probably would not even show up in an OOA/D model because classes like List usually just implement 1:* relationships at OOP time. That is, all one needs to know at OOA/D time is that the collection is ordered in a specific manner. Whether the OOP developer creates a single class dedicated to the specific relationship's ordering or selects one from a generalization in a library is problematic. Most situations I have observed where specialization by constraint is necessary have been related to nonfunctional requirements where computing space implementations become important. Your List example is one of those where the relevant nonfunctional requirement is reuse of collection classes. Unfortunately there are customer problem space situations where specialization by co |