Principles: Tell don't ask, encapsulation, domain object modeling

Unequivocally option 2. Option 1 doesn't actually model anything other  
than relationships. A real domain model reflects relationships thru  
composition but uses behavior to shield peer objects from their API.  
This allows them to act only upon those relationships where the are,  
in the eyes of the domain, subject matter experts. Domain objects like  
Room, Window and Door should all have behaviors. Given the confines of  
the example (which is kind of a bad one, really), Room.closeWindow()  
is perfectly appropriate even though in real life you would probably  
say Person.closeWindow(Room,Window); since Rooms don't actually close  
their own windows... ;)

Hey, it could even be that Person.closeWindow() has private functions  
and state like variables.currentRoom and findClosestWindow(), so  
Person.closeWindow() would (in my model anyway) use Person's state to  
find the closest window in a room.

OTOH, internally, Room's protected scopes could do the same thing thru  
findPesonClosestToWindow().closeWindow(variables.myWindow), or any  
combination of the above. In any and/or all cases though, they all  
focus on encapsulation by implementing the behaviors in the  
appropriate domain object allowing everyone to interact without  
worrying about objects they need't worry about. In providing  
closeWindow(), Room is actually encapsulating the operations required  
to close or open the window and as a result is actually OO.

Along those same lines, option 2 abides by the principle of "Tell,  
don't ask" which is a key OO concept in helping the developer to  
establish behaviors on domain objects. If you're telling a domain  
object to take action in its domain space, you're unconcerned with the  
implementations of it's composites (so you're only working with the  
API of the adjacent object... in this case, the Room) and letting the  
object itself worry about the internal details of actually closing the  
window.

Option one is technically procedural, queueing up operations to be  
executed in sequence by some object that knows far too much about its  
environment. Room.getWindow().close()... asking an object for another  
object, then taking direct action on that object yourself is a very  
procedural approach. It works just fine, but it's not OO... no,  
really, it's not. I promise. "get" is not a behavior! ;)

I'm not saying I like one better than the other, because the "It  
Depends Principle" says that either could be more valid than the other  
depending on context. hehehehe

J

On Feb 12, 2009, at 12:49 PM, Henry wrote:

>
> Let's say.. there's a Room.  Room has Window, and Door.  Room has a
> state (empty, not empty).  And this Room is smart that it only lets
> you close the Window when it is not empty.
>
> So.. we have:
>
> Room.isEmpty()
> Window.open()
> Window.close()
>
>
> Now... since Window.close() needs to check if room is empty first,
> what should be a better solution?
>
> // Solution1:
> Room.init()
> Window.init(room)       // window has reference to Room
> Window.close()           // checks if Room is empty first by calling
> room.isEmpty()
>
>> Room.getWindow().close()
>
>
> // Solution2:
> Room.init(Window window)
> Window.init()               // window has no reference to Room
> Window.close()            // will close itself w/o checking
>
>> Room.closeWindow()   // Room object checks if it isEmpty(), if yes,  
>> then it calls window.close()
>
>
> What do you guys think?  Which one is the better solution? Why? base
> on which OO principle?

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"CFCDev" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/cfcdev?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to