From: Daniel T. on
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
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
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

> 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
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.