So does it mean that the large number of methods in an object is not a concern at all? as long as they're all valid behaviors of the BO?
Regards, Henry On Feb 17, 1:02 pm, Dan Wilson <[email protected]> wrote: > 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 -~----------~----~----~----~------~----~------~--~---
