From: Rick Elbers on 7 Aug 2006 08:56 Op 7 Aug 2006 03:17:52 -0700 schreef "Thomas Kowalski" <th-ko(a)gmx.de>: >> >Therefore I am trying now to grasp as much of the "real" OO as possible >> >with the goal to make my code more easy to understand. >> >> Ok start with cutting all technical things and talk talk talk about >> your domain of application. > >Sorry ( I not 100% sure but this sentence seemed a little bit ironic, >am I right? ;) ) Nope. Its really what OO is or do for you. If you learn to talk about th application domain you will soon see that that talking is exactly waht OOA/D is in essence. > >> >Well, the software I am currently working on is settled in computer >> >graphics. It's a high performance calculation software. Therefore some >> >concepts of business OOA/D are difficult to apply for me. >> >> Please elaborate. The more astonishing oo applications even in the >> start time of ooa/d where in this sector so it might be more easy to >> find good domain references then you think. > >I maybe used the wrong words. After reading some books about OOA/D >it's (still) difficult for me to actually apply it to my problem >domain. One point of confusion was the following example: >The software is working on objects consisting of slices (through the >object) which consist of contours (closed polygons that represent the >surface of the object). At some time these contours need to be divided >/ splittet in smaller contours. This is done using a graph structure. >At first I implemented the methode split as a methode of the class >contour and providing the graph as a parameter (split also might be a >methode of the graph getting the contour as parameter). I guess the >better idea would be to introduce a class ContourSplitter that does the >job by getting a contour and a graph. > Noway. The ContourSplitter what is that ? All but an object. Its the start of the manager-propertybag antipattern in your design. What is your problem with the solution to have Graph and Contour and make the Contour split itself with a Graph ? Since I dunno what exactly graph is in your app and what is does itself we can only say that an equal alternative would be to make the graph produce Contours. That decision I would take simply on the weight of the definition of both classes. Give the least heavy class this new responsibility. Either way we have graph and contour and nothing more. (btw a totally different option arise from Contour as a Composite( see GOF) but thats for later). >Sorry for the (unneccessary?) details, but its the only way I guess to >avoid misunderstandings. > For from unneccessary. We need a few more details about "graph" >> >Basicly I am working on the assumption that an object encapsulates the >> >methodes to manipulate itself, with might be not really right on second >> >thought. >> >> In my experience Its always right. Sorry to say it that brutal but >> believe me the tension that it brings helps you in the right way most >> often > >See the example before. The contour needs to be divided, therefore at >first glance it might appear right to add the methode split to this >class. But that blows the classes code far too much. Aha. Good argument. Give the responsibility to the graph then. Graph: splits contours >First attempt to reduce the codelength of the classes contour was to >subclass it, resulting in a class like DividableContour. Are there contours that are not ? where is this type of contour mentioned in literature ? > On second >thought it might be advisible to rather introduce a new class like >ContourSplitter that makes the "dirty work". No. Lets see what you say. You tell me that your class Contour is to big ? Lets delve deeper. List all its responsibilities and then lets try to group those responsibilities. Finding the corresponding objectname can be a challenge but surely it will deepen your understanding of the domain. Read about it everywhere. You can look at it this way: if you still have to heave classes that means your domain understanding is still insufficient. Put it another way: if you now create that class ContourSplitter later on you will notice that this class blurs the vision on your domain, and that there is a much more natural way of dividing contour his responsibilities over understandable objects. > >> Define as many strong independent objects as you can BEFORE going into >> scenario's or technical implemenation detail( which often is a like). > >That would be the contour and the graph in my case. Thats it. > >> Dont bother about relations between objects at all at first. You will >> see then that some rather obvious relations for behaviors arise. > >I totally agree. But there are a lot of border cases for unexperienced >developers like me. Therefore I would like to know more about metrics, >pitfalls, usage stories that might help to make the "right" decision (I >guess there is no right but only a well working decision). Yes. You seem to be very open to learn which is the most important thing as designer imho. Then again you might be a little bit technically biased. Metrics might help experienced designers, but applying a lof of simple heuristics like "do it myself" provide enough help at first > >> That kind of relations at the behavioral level can be considered ok as long >> as they dont compromise the firm object identity that you established >> upfront... > >But what to do if they do actually compromise the firm object identity, >or at least seem to at first? > Then you have a language problem or a problem in domain knowledge rather then a ooa/d problem directly. Give an example ? >Thanks again for taking the time to help me, >Thomas Kowalski Ofcourse. Its been fun sofar, Rick
From: Thomas Kowalski on 7 Aug 2006 12:15 > Nope. Its really what OO is or do for you. If you learn to talk about > the application domain you will soon see that that talking is exactly > what OOA/D is in essence. Well, im my case I am rather creating a new domain. Or maybe rather a subdomain. The process used by my softwares algorithm is unique and as far my research goes (master thesis), there is no appropriate domain language to describe it. Therefore I just treat my algorithm described in natural language as the domain describtion. >> I guess the better idea would be to introduce a class ContourSplitter >> that does the job by getting a contour and a graph. > > Noway. The ContourSplitter what is that ? All but an object. Its the > start of the manager-propertybag antipattern in your design. What exactly is this antipattern? Do you have some links that explain it/ gives examples? Isn't it right that the way you describe OOA/D is rather the development of the domain model, which takes place in the initial analysis phase? Isn't it true that the class model is just a domain modell adapted to the underlying technologie? Shouldn't it provide an higher level of maintainabilty by chunking the classes in an "appropriate way"? Althought your approach seems to capture the requierment of easy to understand, but does maintainability is much more then that? Like e.g. seperation of concerns? As far as I have read about agile development and refactoring in particular, isn't it the idea to structure classes, methodes etc. to provide higher maintainablity (which includes of course easier understanding of the programm flow)? So far I have written code even myself could not understand 2 months later. Therefore I might be a little biased by taking maintainabilty as the highest goal of OOA/D. Another example: The software is used for reconstruction of the objects surface out of given points. Using the logic so far it would mean that reconstruction is a part of the the object. Moreover the reconstruction process/algorithm is divided into a matching phase, simple and complex reconstruction. To make the concepts clear I created an object that is calling an "triangulation service" class that in turn invokes the methodes of the "matching" class, the "simple reconstruction" class and so on. > What is your problem with the solution to have Graph and Contour and > make the Contour split itself with a Graph ? Well, as stated later, it blows the code and makes the inital concept of a contour difficult to understand. Thenever I use a framework I always wish that the intended programm flow should be obvious despite the fact that the framework was extended several times and all the new classes and especially methods are appended. > Give the least heavy class this new responsibility. Somehow I am not really comfortable doing so. I am still searching for some justification to put some responsibilities / behaviour in a certain class. Because I can't see whether to put the "divide" methode in the graph or the contour, I would thing that it might be good to add a class that makes it purpose clear. > Either way we have graph and contour and nothing more. (btw a totally > different option arise from Contour as a Composite( see GOF) but thats > for later). As I understood the composite pattern its used to describe recursive structures. In the case of my contour class it's not really appropriate. I guess you mean that a contour consist of many contours/contour parts. But that's not the case. Or do you man that I should group some of the responsibilities / methodes of the class and implement it in an class aggregated by the contour? Like for example the contours area is approximated by the bounding box (this is for sure a class ;) ). A methode contour.area() would therefore delegate to the member box with is an instance of the class bounding box and it's methode box.area(). > Far from unneccessary. We need a few more details about "graph" The graph is an arbitray set of points connected by edges. In the context the methode "split" of the edges can be seen as "knifes" that penetrate the contour. they introduce new edges in the contour and divide it at any arbitrary place in any number of (sub-)contours (closed polygons), just like a knifes (a single edge) cut a cake (the border of the cake is a closed contour). >> First attempt to reduce the codelength of the classes contour was to >> subclass it, resulting in a class like DividableContour. > > Are there contours that are not ? No, there is just one typ of contour used throughout the whole software. The hierarchy would be something like: contour extends dividablePolygon extends closedPolygon > where is this type of contour mentioned in literature ? No literature besides my thesis exist at the moment as far as I know. >> On second thought it might be advisible to rather introduce a new class >> like ContourSplitter that makes the "dirty work". > > You can look at it this way: if you still have to heave classes that means > your domain understanding is still insufficient. That was the case then I started to write the software. Now I guess I have sufficent knowledge. But of course this depends on what you call the "domain". None of the classes/objects exisit in the real world. They are all introduced by a certain way of seeing the problem and by the development of an algorithmen that solves it. I would call this description - in some way smilar to an use case - of the process and the steps done during the execution the domain. > Put it another way: if you now create that class ContourSplitter later on you > will notice that this class blurs the vision on your domain, and that there > is a much more natural way of dividing contour his responsibilities over > understandable objects. I guess that is what happened in most of the frameworks I am using ;) I see that problem and see the importance, but this would lead nearly automaticly to big classes in my understanding. For sure some trade-off is necessary. Perhaps you can explain why you state that an sufficent domain knowledge helps to reduce the class size? Another point would be, that it would seperate concerns. The class contour don't need to know anything about the graph. If the "glue-class" ContourSplitter will bother, then it might be easier to change easier the way a contour is divided/splitted. > Def
From: Rick Elbers on 7 Aug 2006 16:46 Op 7 Aug 2006 09:15:21 -0700 schreef "Thomas Kowalski" <th-ko(a)gmx.de>: >> Nope. Its really what OO is or do for you. If you learn to talk about >> the application domain you will soon see that that talking is exactly >> what OOA/D is in essence. > >Well, im my case I am rather creating a new domain. Or maybe rather a >subdomain. The process used by my softwares algorithm is unique and >as far my research goes (master thesis), there is no appropriate domain > >language to describe it. Therefore I just treat my algorithm described >in natural language as the domain describtion. > This might be the real problem. Are you absolutely sure nobody in the world has thought about this kind of things before ? Then you can also ask yourself the question: can this domain be considered a methapor for another domain in which a lot more is published ? If so you can maybe translate a few object terms from the more know domain. >>> I guess the better idea would be to introduce a class ContourSplitter >>> that does the job by getting a contour and a graph. >> >> Noway. The ContourSplitter what is that ? All but an object. Its the >> start of the manager-propertybag antipattern in your design. > >What exactly is this antipattern? Do you have some links that explain >it/ gives examples? > The anti pattern has to do with systems. The objects in a system are balancing each other to provide the needed equilibrium in the whole system. You might look up work of of for instance Bateson to learn more about systems theory. In this example it means that if you are starting to have objects which mainly encapsulate behavior and no state somewhere else you will have objects which display the opposite: state but no behavior( I call that property bags). In my experience good ooa/d has to do with finding true OBJECTS that is things that do AND know( ergo has state AND behavior). >Isn't it right that the way you describe OOA/D is rather the >development of the domain model, which takes place in the initial >analysis phase? It is mainly a good domain model, which takes place during all development fases. A good domain model even triggers new or sharpened requirements, but domain "fluency" is much more needed when we reach the fase which is sometimes called "technical design"( which name I ofcourse not support, detailed design is a much better term because it doesnt rule out non-technicians.) > Isn't it true that the class model is just a domain >modell adapted to the underlying technologie? Yes it should be. Most often technicians take over somewhere and they most often dont bother the least with the domain and the most with the "working" application. > Shouldn't it provide an >higher level of maintainabilty by chunking the classes in an >"appropriate way"? This I understand as being more "fluent" in the domain or more expressive if you want. You need concepts( or objects) even in the highly unlikely case of a *new* domain( which imho dont really exist) >Althought your approach seems to capture the >requierment of easy to understand, but does maintainability is much >more then that? Like e.g. seperation of concerns? > I dont think I understand exactly what you mean here , nor do I think we should bother with this if basics are violated. >As far as I have read about agile development and refactoring in >particular, isn't it the idea to structure classes, methodes etc. to >provide higher maintainablity (which includes of course easier >understanding of the programm flow)? So far I have written code even >myself could not understand 2 months later. Therefore I might be a >little biased by taking maintainabilty as the highest goal of OOA/D. > Maintanabilty is partly the same as understandability ? In every case you dont earn much by splitting of manager classes. Certainly not becase you should know that this manager classes require not independently userful "property bags". If an object cant do what it should or isnt what it should be for layman your maintainability is maybe not helped either. >Another example: The software is used for reconstruction of the objects >surface out of given points. Using the logic so far it would mean that >reconstruction is a part of the the object. It might. I would search in general for the least "strong" object to attach the responsibility too. In this case that would be point instead of object. >Moreover the reconstruction >process/algorithm is divided into a matching phase, simple and complex >reconstruction. Then the questions. What would you call the series of points in the matching phase ? Might this be an object ? could it have a recognizable name ( ) What is the essential difference between simple en complex reconstruction and what are start and end of those phases ? Can you find names for both series of points as a RESULT of both ? Resultants of an algorithm often provide nice "objects" since it most of the times is something you strived for ... >To make the concepts clear I created an object that is >calling an "triangulation service" class that in turn invokes the >methodes of the "matching" class, the "simple reconstruction" class and >so on. > Does that mean that somebody who can follow the words of your thesis can also understand the software ? >> What is your problem with the solution to have Graph and Contour and >> make the Contour split itself with a Graph ? > >Well, as stated later, it blows the code and makes the inital concept >of a contour difficult to understand. Thenever I use a framework I >always wish that the intended programm flow should be obvious despite >the fact that the framework was extended several times and all the new >classes and especially methods are appended. > Sorry I dont understand your problem with the two classes. The concept of the contour should encapsulate what you do to a contour. That might be one of the main rules of software design. That makes objects do things that in the real world other objects do to them. Thats your responsibility as the novel writer. Give some objects more and others less responsibilities. >> Give the least heavy class this new responsibility. > >Somehow I am not really comfortable doing so. I am still searching for >some justification to put some responsibilities / behaviour in a >certain class. Because I can't see whether to put the
From: Ed on 7 Aug 2006 18:53 Rick Elbers skrev: > > The anti pattern has to do with systems. The objects in a system are > balancing each other to provide the needed equilibrium in the whole > system. You might look up work of of for instance Bateson to learn > more about systems theory. In this example it means that if you are > starting to have objects which mainly encapsulate behavior and no > state somewhere else you will have objects which display the opposite: > state but no behavior( I call that property bags). In my experience > good ooa/d has to do with finding true OBJECTS that is things that do > AND know( ergo has state AND behavior). > Hi, folks, An interesting discussion you're having, though I must admit, I'm not entirely sure I've understood the direction it's taking, so I apologise in advance for any misunderstandings. Firstly (I'll reference all from this post rather than isolated replies), Thomas you mentioned in your first post that, "My idea was to simplify huge classes by dividing them ..." and Rick replied, "If you have huge classes probably your problem domain is insufficiently analysed;" with which I agree. Then Thomas you wrote that, "Basicly I want to use it to provide a way to safe memory ressources in case application that base on a similar datastructure are merged to one application," which I hope you'll forgive me by rephrasing (if I understand correctly) as, "Basicly I want to use it to provide a way to save memory ressources in case this application and an application that's based on a similar datastructures are merged to one application." So you're working on one application, and think it might be merged with another existing application out there at some time in the future. I'm not entirely convinced that two applications can be cost-effectively merged just because they share the same data-structures; most banking applications would share the same data-structures, I imagine, but merging VISA's banking system with the system used by Citibank sounds like a nightmare to me. The important thing here, however, is that you're looking to, "Save memory resources," and that's not a primary goal of OO. (A very minor point - and here perhaps I'm misunderstanding just for the sake of it - but Rick then gave the advice, "Define as many strong independent objects as you can ...;" I've never seen an independent object myself :)) (There's no good way to end a bracketted aside that ends with a smiley, is there?) Then we come to what may be the central problem here when Thomas says, "Somehow I am not really comfortable doing so. I am still searching for some justification to put some responsibilities / behaviour in a certain class. Because I can't see whether to put the "divide" methode in the graph or the contour, I would thing that it might be good to add a class that makes it purpose clear." Thomas: it's ok. There's no Absolute Software Law out there that says it's better to put method X in Class A rather than Class B in the border cases that you're talking about; no policia will tear you from your bed one stormy Tuesday night. For me, OO is flexibility through variance encapsulation: so if you're not sure in which class to put a method, consider how the classes will develop over time; if your abstractions are sound, and one abstraction will clearly offer more implementations in future than the other, then it should own the method. I know that, "If your abstractions are sound," clause is exactly the question you're asking, but thinking about flexibility (not memory-resource savings or, as you mentioned somewhere else, understandability) will generally see you on the right path. Another important question to come out of all this is: what is the granularity of your encapsulation? In other words: are you using C++ namespaces? I presume you're not, as you are asking very class-grained encapsulation questions. Some of your problems are solved by namespaces, as you then have a much larger grain of encapsulation, and so you're free to hand over much, "Bigger," problems to other parts of your code. This is not a small point. With namespaces you can have most of your code say, "Well, I don't care whether a Contour or a Polygon or ContourSplitter does what I want, I'll just hand this over to GraphFacade, and let it worry about whether it wants to delegate or pass to a subclass." This encapsulates one part of your code from another, thereby making it more flexible, and that's the bottom-line (particularly if you're employing a hierarchical namespace, see: http://www.edmundkirwan.com/servlet/fractal/cs1/frac-cs70.html). Finally, we come to Rick's, "In my experience good ooa/d has to do with finding true OBJECTS that is things that do AND know( ergo has state AND behavior)." I'd be hesitant to make so broad a statement as, "Objects should have bevahiours and state." It could be argued that the GOF state pattern, for example, decomposes behaviour into a central object that's aware of the state (the context) and all the individual state objects that, themselves, just contain behaviour (for their unique states) (see my own small offerings, in which a series of states have no state information themselves [apart from knowing which state comes next] and just own behaviour at:) http://www.edmundkirwan.com/servlet/fractal/cs1/frac-cs60.html ..ed -- www.EdmundKirwan.com - Home of the Fractal Class Composition
From: Rick Elbers on 8 Aug 2006 03:11
Hi Ed, Thanks for your interesting remarks. Re-reading my own messages it seems a lot of them are stated way to absolute. Thanks for your response in that respect. Ofcourse you are very right to say: > "There's no Absolute Software Law out there that says > it's better to put method X in Class A rather than Class B" Then again for me and for the people whom I teach and mentor there are quit a few quidelines or heuristics that seem to work in making those decisions. Most of them are non-technical in nature, and in my experience that constitutes a big part of the problem for mostly technical oriented people. When you say: > "For me, OO is flexibility through >variance encapsulation: so if you're not sure in which class to put a >method, consider how the classes will develop over time" It might be an ideal case where domain specialists and object designers also make a prognosis about the state of the domain in say 5 years. Lots of times I dont see that effort made. Then with the "variance encapsulation" argument we might create a "purely technical" discussion about object design. From that we might have objects less recognizable by domain experts just for "the sake of technical arguments". I see that kind of "technical design" happen and see it beat up every domain modelling effort very fast. Mostly with it you get comments about the "idealistic or unrealistic" analysis model. Its not my way. Flexibility alone is not a good argument for a design imho. That might drive us into abstractions for the sake of being abstract. I consider that another way of the technicians taking over design. Seen that too. What we might need more is goal oriented abstraction for which domain concepts provide good objects. And it should too. To me its the responsibility of the domain/business to give enough of a differentiated view of itself so that it can modelled in software and in business. Then about design patterns you comment " >I'd be hesitant to make so broad a statement as, "Objects should have >bevahiours and state." It could be argued that the GOF state pattern, >for example, decomposes behaviour into a central object that's aware of >the state (the context) and all the individual state objects that, " Yes ofcourse lots of design patterns ( how about strategy for instance) show tendencies towards either managerial omnipotence or property bag impotence. The whole distinction between behavioral and structural patterns in the GOF book points to this. The interesting aspect being for me that although they all show tendencies towards either site nowwhere but in the state/strategy patterns it seems totally out of balance. The primary heuristic you cited above for me is of a different level. If designers are competent to work with the primary, the patterns of collaboration between objects and classes will arise more naturally. Therefore in my experience it might even be ill-advised to work directly with design patterns catalogs. It has the risk of overemphasizing collaborations between objects where object identitiy, recognizability and independency might be offered. Thats probably the reason I throw some very absolute statements too. Its not so easy to really work with the primary and to keep working with its effects and we get easily distracted into "sound technical discussions" or pretty sounding technical discussions about object design. Regards, Rick Op 7 Aug 2006 15:53:49 -0700 schreef "Ed" <iamfractal(a)hotmail.com>: > >Rick Elbers skrev: > > >> >> The anti pattern has to do with systems. The objects in a system are >> balancing each other to provide the needed equilibrium in the whole >> system. You might look up work of of for instance Bateson to learn >> more about systems theory. In this example it means that if you are >> starting to have objects which mainly encapsulate behavior and no >> state somewhere else you will have objects which display the opposite: >> state but no behavior( I call that property bags). In my experience >> good ooa/d has to do with finding true OBJECTS that is things that do >> AND know( ergo has state AND behavior). >> > >Hi, folks, > >An interesting discussion you're having, though I must admit, I'm not >entirely sure I've understood the direction it's taking, so I apologise >in advance for any misunderstandings. > >Firstly (I'll reference all from this post rather than isolated >replies), Thomas you mentioned in your first post that, "My idea was to >simplify huge classes by dividing them ..." and Rick replied, "If you >have huge classes probably your problem >domain is insufficiently analysed;" with which I agree. > >Then Thomas you wrote that, "Basicly I want to use it to provide a way >to safe memory ressources in >case application that base on a similar datastructure are merged to one >application," which I hope you'll forgive me by rephrasing (if I >understand correctly) as, "Basicly I want to use it to provide a way to >save memory ressources in >case this application and an application that's based on a similar >datastructures are merged to one application." So you're working on one >application, and think it might be merged with another existing >application out there at some time in the future. I'm not entirely >convinced that two applications can be cost-effectively merged just >because they share the same data-structures; most banking applications >would share the same data-structures, I imagine, but merging VISA's >banking system with the system used by Citibank sounds like a nightmare >to me. The important thing here, however, is that you're looking to, >"Save memory resources," and that's not a primary goal of OO. > >(A very minor point - and here perhaps I'm misunderstanding just for >the sake of it - but Rick then gave the advice, "Define as many strong >independent objects as you can ...;" I've never seen an independent >object myself :)) (There's no good way to end a bracketted aside that >ends with a smiley, is there?) > >Then we come to what may be the central problem here when Thomas says, >"Somehow I am not really comfortable doing so. I am still searching for >some justification to put some responsibilities / behaviour in a >certain class. Because I can't see whether to put the "divide" methode >in the graph or the contour, I would thing that it might be good to add >a class that m |