|
From: Daniel T. on 15 Jan 2008 11:23 Veloz <michaelveloz(a)gmail.com> wrote: > Thanks for all your posts. I wonder if I am confusing people by using > the word "container". > > In my case I am not talking about a language supplied container, such > as an array, list, dictionary, etc. I am talking developing a > software class (to mirror what's going on in the domain) that holds of > a number of other objects. > > Because this top level class is comprised of ("has") a number of other > classes, I refer to it as a container. Maybe I shouldn't do that. No confusion at all. > Now, there are a few things I'm trying to accommodate in the design: > > 1. I would like the design to mimic the domain. As such, I would have > a PartsDrawer class that can hold (have/contain) one Toolbelt and any > number of Magic-Bins > > 2. We have a business rule that says the objects put into a > PartsDrawer can't have a same colored screw in them. That is, if you > have a red screw in a Toolbelt, that's in a particular PartsDrawer, > you can't add a Magic-bin to this particular PartsDrawer if that Magic- > bin also contains a red screw. Given the above, your PartsDrawer class *cannot* make its Toolbelt and magicBins public (even indirectly through a method.) If it did, then anybody would be able to put any color screw in them and the Toolbelt would not be able to ensure its invariant. > [very good explination snipped] > > Sorry if this doesn't make sense. This has been a very confusing > project for me with all sorts of weird domain relationships.. It makes complete sense. You don't have an OO design, you have a Representational design. I quote Robert C Martin: Employing methodologies that confuse OOA and representational modeling leads to some unfortunate consequences. Consider again the game of Blackjack. If we believed that our representations of Cards, Decks, and Hands were the objects in the system, we would search for behaviors that implement the rules of Blackjack within these objects... Doing these things, however would mean that the once-elegant representational scheme that could represent any game of cards could now represent only a game of Blackjack. True, we can derive BlackjackHand and PokerHand from an abstract base Hand, but then Poker games must explicitly use PokerHand objects and Blackjack games must explicitly use BlackjackHand objects. We have lost the reusability of the representation. In OOA we try to find behavioral abstractions as opposed to representational abstractions. In an OO analysis of Blackjack, cards and decks could be abstracted away to some generalized scoring tokens. The primary abstracts might be the dealers and players...
From: Veloz on 15 Jan 2008 14:21 Thanks for your reply, I always look forward to them :-) > Given the above, your PartsDrawer class *cannot* make its Toolbelt and > magicBins public (even indirectly through a method.) If it did, then > anybody would be able to put any color screw in them and the Toolbelt > would not be able to ensure its invariant. > Yes, I sensed that PartsDrawer needs full control/awareness over its parts to insure the business rules were always applied and thus the PartsDrawer object is always in a valid state. My solution (he says sheepishly) was to implement the observer pattern. The toolbelt and the MagicBins would each fire an event whenever their content was changed. When you add Toolbelt and MagicBins to a PartsDrawer, the PartsDrawer would hook those events.. and each time the event was triggered, PartsDrawer would call an internal Validate() method that would make sure all the screws were the same color. Is this a total hack??? > It makes complete sense. You don't have an OO design, you have a > Representational design. I can see that. A good part of my application objects are representational... Sometimes I feel like this is "bad" but I always come back to the same conclusion: somewhere in my design I *do* have to honor and enforce the representational relationships dictated by the domain. In my example above, the software must ultimately present the user with something known as a PartsDrawer that appears to contain ToolBelts and MagicDrawers. The software must also enforce the rule about not repeating a screw color, and it must insure that the user doesn't try to put a Saw in the PartsDrawer, and so on. In short, it seems like the application has to know a lot of details about the relationship between PartsDrawer, Toolbelts, and MagicBins.. so why try and "hide" these details somewhere else? ... An example of this, if you'll bear with me. I read recently in an OOAD book an example of a musical inventory software program that allowed adding musical instruments to the system and then allowing searching across those instruments (using various criteria) to find matches. In the earlier, "not so good" designs the example showed the developer creating specific musical instrument classes, such as Guitar, each having properties that were unique to them. The search method knew the properties of these classes and could access them while performing a Search in order to match user-entered search criteria. Of course, this design becomes troublesome because there is no re- usability across these instrument classes - and it becomes hard to maintain. Each time you add a new instrument to inventory, you need a new class with its own properties,and you also have to modify other parts of your system to recognize those properties, and so on. Ultimately the author ended up showing a more generic solution based on an "instrument" class that holds a list of features and their price. When you build an instrument object, some creator merely populates the features and prices that are appropriate for that instrument into this list - thus getting away from having specific properties per instrument (properties such as number of strings, whether it was wood or synthetic, and so on). I agree that this makes the instrument class much more flexible (you can describe any instrument using it, and you can have varying amounts of information per instrument without having to statically define everything) but here's the problem I have: The author makes it sound like the whole application design was fixed by this miraculous invention of generalizing the details.. and that if we write every class this way... trying to neutralize or generalize away the specifics and details.. we would end up with a great application. But the problem I always end up with is this: *Somewhere*, the very specific details of the domain have to end up in your application. You can't generalize everything away, or you'll have a bunch of generalities that can't perform the specified functions set by your requirements. So where do the specific go?? In the instrument example, the author never did go back to showing how we would implement a Search facility. Could the search facility merely have used the new instrument classes and no more information than they contained in their list of properties? I doubt it.. How would the Search show the users which kinds of properties they could search on? Would it have to scan every instrument object in the system, accumulating a list of all the properties contained in the lists of all the instrument objects??? I suppose that might be possible... but then if the user wanted the search criteria grouped somehow, for example, search criteria for stringed instruments, or percussion instruments, how would Search known how to arrange all these properties by various classifications. I'm not asking you to explain what this author had in mind, I'm merely trying to convey my own frustration / inadequacy at generalizing parts of my design - it always seems that the details just end up getting pushed to somewhere else.. so what have I really saved?? Michael > > I quote Robert C Martin: > > Employing methodologies that confuse OOA and representational > modeling leads to some unfortunate consequences. Consider again the > game of Blackjack. If we believed that our representations of Cards, > Decks, and Hands were the objects in the system, we would search for > behaviors that implement the rules of Blackjack within these > objects... > > Doing these things, however would mean that the once-elegant > representational scheme that could represent any game of cards could > now represent only a game of Blackjack. True, we can derive > BlackjackHand and PokerHand from an abstract base Hand, but then > Poker games must explicitly use PokerHand objects and Blackjack games > must explicitly use BlackjackHand objects. We have lost the > reusability of the representation. > > In OOA we try to find behavioral abstractions as opposed to > representational abstractions. In an OO analysis of Blackjack, cards > and decks could be abstracted away to some generalized scoring > tokens. The primary abstracts might be the dealers and players...
From: Daniel T. on 15 Jan 2008 22:31 Veloz <michaelveloz(a)gmail.com> wrote: > > Given the above, your PartsDrawer class *cannot* make its Toolbelt and > > magicBins public (even indirectly through a method.) If it did, then > > anybody would be able to put any color screw in them and the Toolbelt > > would not be able to ensure its invariant. > > Yes, I sensed that PartsDrawer needs full control/awareness over its > parts to insure the business rules were always applied and thus the > PartsDrawer object is always in a valid state. > > My solution (he says sheepishly) was to implement the observer > pattern. > > The toolbelt and the MagicBins would each fire an event whenever their > content was changed. > > When you add Toolbelt and MagicBins to a PartsDrawer, the PartsDrawer > would hook those events.. and each time the event was triggered, > PartsDrawer would call an internal Validate() method that would make > sure all the screws were the same color. > > Is this a total hack??? What does the PartsDrawer do if the screws aren't the right color? Does it change them, (which would surprise the client that put the screw in,) or does it throw an exception (which means it is the client who has to track the color, not the PartsDrawer?) If the answer is the latter (which is what I suspect) then your solution is staring you in the face. :-) The clients are already making sure the screws are the right color, so the PartsDrawer is superfluous. Just use a system provided container class. > > It makes complete sense. You don't have an OO design, you have a > > Representational design. > > I can see that. A good part of my application objects are > representational... Sometimes I feel like this is "bad" but I always > come back to the same conclusion: somewhere in my design I *do* have > to honor and enforce the representational relationships dictated by > the domain. No you don't. You have to honor and enforce the behavioral relationships dictated by the domain. That's what OO is about. > An example of this, if you'll bear with me. I read recently in an > OOAD book an example of a musical inventory software program that > allowed adding musical instruments to the system and then allowing > searching across those instruments (using various criteria) to find > matches. In the earlier, "not so good" designs the example showed the > developer creating specific musical instrument classes, such as > Guitar, each having properties that were unique to them. The search > method knew the properties of these classes and could access them > while performing a Search in order to match user-entered search > criteria. > > Of course, this design becomes troublesome because there is no re- > usability across these instrument classes - and it becomes hard to > maintain. Each time you add a new instrument to inventory, you need a > new class with its own properties,and you also have to modify other > parts of your system to recognize those properties, and so on. > > Ultimately the author ended up showing a more generic solution based > on an "instrument" class that holds a list of features and their > price. When you build an instrument object, some creator merely > populates the features and prices that are appropriate for that > instrument into this list - thus getting away from having specific > properties per instrument (properties such as number of strings, > whether it was wood or synthetic, and so on). > > I agree that this makes the instrument class much more flexible (you > can describe any instrument using it, and you can have varying amounts > of information per instrument without having to statically define > everything) but here's the problem I have: The author makes it sound > like the whole application design was fixed by this miraculous > invention of generalizing the details.. and that if we write every > class this way... trying to neutralize or generalize away the > specifics and details.. we would end up with a great application. > > But the problem I always end up with is this: *Somewhere*, the very > specific details of the domain have to end up in your application. You > can't generalize everything away, or you'll have a bunch of > generalities that can't perform the specified functions set by your > requirements. So where do the specific go?? > > In the instrument example, the author never did go back to showing how > we would implement a Search facility. Could the search facility merely > have used the new instrument classes and no more information than they > contained in their list of properties? I doubt it.. How would the > Search show the users which kinds of properties they could search on? > Would it have to scan every instrument object in the system, > accumulating a list of all the properties contained in the lists of > all the instrument objects??? I suppose that might be possible... but > then if the user wanted the search criteria grouped somehow, for > example, search criteria for stringed instruments, or percussion > instruments, how would Search known how to arrange all these > properties by various classifications. > > I'm not asking you to explain what this author had in mind, I'm merely > trying to convey my own frustration / inadequacy at generalizing parts > of my design - it always seems that the details just end up getting > pushed to somewhere else.. so what have I really saved?? If this example is anything like your application, then maybe there isn't any interesting behavior. Maybe OO isn't the way to go.
From: Veloz on 16 Jan 2008 11:13 > No you don't. You have to honor and enforce the behavioral relationships > dictated by the domain. That's what OO is about. Wow, that really got me thinking. .. I suspect this line of thought is related to the quote you sent from Martin, in which he talks about not designing the solution by mimicking the domain entities and their relationships, but rather by.. I guess.. finding the "essence" of the responsibilities that have to be provided for in the domain (aka the behaviors) and then modeling those. Yes?
From: Daniel T. on 16 Jan 2008 13:13 On Jan 16, 11:13 am, Veloz <michaelve...(a)gmail.com> wrote: > > No you don't. You have to honor and enforce the behavioral relationships > > dictated by the domain. That's what OO is about. > > Wow, that really got me thinking. .. I suspect this line of thought > is related to the quote > you sent from Martin, in which he talks about not designing the > solution by mimicking the > domain entities and their relationships, but rather by.. I guess.. > finding the "essence" of the > responsibilities that have to be provided for in the domain (aka the > behaviors) and then modeling > those. > > Yes? Right. Unless, of course, you are writing a database application, where you are basically taking data, transforming it (in some possibly very complex way,) then presenting it to the user.
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 Prev: ANN assert_efficient_sql Next: Refactoring into ravioli code |