No, I'm sorry this is not a real app.  I am building something else, but I
don't think it is appropriate for me to post the actual software model we're
working on at work.  I'm not sure if my client will be okay with me asking
on a public mailing list.

Although the Room / Window example sounds ridiculous on the surface, it is
where the methods should be placed that puzzled me.

To use a super abstract example, it'll be like..

1 ObjectA has an ObjectX, ObjectY, and ObjectZ.

ObjectX, ObjectY and ObjectZ have n public methods each (where n may be =
10+).

If I push all behaviors onto ObjectA, then A will have all 30+ public
methods (+ its own).  Yes, we'll respect the Law of Demeter, and no one will
know ObjectA really has ObjectX/Y/Z, but wouldn't ObjectA become super fat?


Regards,
Henry Ho


On Tue, Feb 17, 2009 at 1:06 PM, Peter Bell <[email protected]> wrote:

>
> I'm a little confused. Do you actually have a customer paying you to
> build the application below? If not, and you are building a real OO
> app I'd suggest using that as the example. There are only rules of
> thumb in OO design and they are incredibly context specific. Try
> asking an artist "which color is best" for a painting . . . As such,
> using some kind of generic example is usually a really bad way to go
> (which was why I always hated the OO books talking about engines being
> composed within a car).
>
> Of course, apologies if this is a real app that you *are* building
> right now for a client to mock up a room control system or something.
> It's just not all that often I see such apps in the CF world.
>
> Best Wishes,
> Peter
>
>
> On Feb 17, 2009, at 3:45 PM, Henry 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?
> > >
>
>
> >
>

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