Solution 2 is preferable. Here's why.
The following functions:
Room.canCustomizeWindow()
Room.canSelectStyle()
Room.hasCeilingFan()

 are behavior and have been extrapolated from the requirements and the
intend has been made concrete in code. Now anyone who wants to know the
answer to these questions, merely has to ask the object. Additionally, when
the implementation behind any of these changes, the method body itself only
has to be updated.


Lets look at your other design:

Room.getPlan().isEnable("customizeWindow")
Room.getPlan().isEnable("selectStyle")
Room.getPlan().isEnable("ceilingFan")

Firstly, we have to ask an object for another object which sort of runs
against the Law of Demeter (http://en.wikipedia.org/wiki/Law_of_Demeter). (I
personally look at it as the Guideline of Demeter, but it is usually a good
practice to follow)


Secondly, we have some generic isEnable with a magic string defining the
rule. Under the covers, this means all your implementation is either stuck
in a switch case statement (big yuck) or delegated out to methods. You now
also have to handle all sorts of validation and error conditions if an
invalid string is passed in.
Regardless, it is unclear by looking at the object, exactly what the object
knows and can do....


Wrapping up implementation into addressable, well named methods is a big
part of good OO programming.



DW
















On Tue, Feb 17, 2009 at 3:45 PM, Henry <[email protected]> wrote:

>
> The Room object is getting bloated, what should I do?
>
> Room has Windows, and you guys advised me to use Room.closeWindow().
> That's what I did.  However, instead of one getWindow() function in
> Room, Room now has 10 methods related to operations for Window.
>
> Now Room also has an owner of type User , and owner handles the login
> (), changePassword(), etc.
> Room has an owner, that makes sense.
> Which solution's better now?
>
> Solution 1:  // 1 getOwer() method in Room
>
> Room.getOwner().changePassword(oldPassword, newPassword)
> Room.getOwner().validatePassword(password)
> Room.getOwner().setName(newName)
>
>
> Solution 2:  // 3 methods in Room
>
> Room.changeOwnerPassword(oldPassword, newPassword)
> Room.validateOwnerPassword(password)
> Room.setOwnerName(newName)
>
>
> How about... Plan?  Let's say Plan has method isEnable(featureName).
> The view layer needs to call this function to determine which Tab to
> show.
> Room has a plan, that makes sense.  (One user can have many Rooms,
> each Room has a plan)
>
>
> Solution 1:  // 1 getPlan() method
>
> Room.getPlan().isEnable("customizeWindow")
> Room.getPlan().isEnable("selectStyle")
> Room.getPlan().isEnable("ceilingFan")
>
>
> Solutions 2:
> Room.canCustomizeWindow()
> Room.canSelectStyle()
> Room.hasCeilingFan()
>
> Now I'm confused.  Do you guys still think solution 2 is the preferred
> choice?  Even thought it can make my Room object bloated with several
> times more methods?
>
>
> Thank you!
> Henry Ho
>
>
> On Feb 12, 12:53 pm, Henry <[email protected]> wrote:
> > Thanks a lot.
> >
> > I liked Solution 2 too, but found the method Room.closeWindow() a
> > little awkward.  I guess it is actually fine, after hearing the
> > reasons from you guys.
> >
> > Yes, this is a high tech room that closes its own Window. :)
> >
> > Henry Ho
> >
> > On Feb 12, 11:20 am, Jared Rypka-Hauer <[email protected]>
> > wrote:
> >
> > > 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?
> >
>


-- 
"Come to the edge, he said. They said: We are afraid. Come to the edge, he
said. They came. He pushed them and they flew."

Guillaume Apollinaire quotes

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