designing beyond MV and (one) C

  • Hi All,

    Until now I've been doing very simple apps with a number of model
    classes, a view, and a single controller.

    I am now going to try a more complicated interface, but don't quite
    understand how to apply the MVC paradigm in this case. (Just to be
    clear, this is NOT a document app, just a plain Cocoa app.)

    I'm building a utility to take various types of data and parse them
    according to my settings. I'm looking to have an introductory window
    that asks what type of file the user wants to parse. Then based on
    the response, I open the appropriate window to gather data about the
    file to be handled. Separate interfaces will be used for the
    different types of parsing operations.

    In the MVC paradigm, do you typically use a different controller for
    each major interface? Should I have three controllers, one to handle
    each type of parser? Three window controllers, to handle each major
    settings interface?

    What about nib files? I've read that putting everything in separate
    nibs is more efficient in terms of loading time, but for quick and
    dirty apps, it would be nice to be able to use the "one nib has all"
    approach as well. Besides, this is not a time-critical app.

    Currently, I have one controller, four windows (intro, and three for
    the different setting types), all in one nib file. I can open and
    close the separate windows fine. But is that bad design?

    Thanks.

    Daniel
  • On Jan 12, 2008, at 2:39 PM, Daniel Child wrote:

    > In the MVC paradigm, do you typically use a different controller for
    > each major interface?
    >
    This is discussed in  <http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaFundamentals
    /CocoaDesignPatterns/chapter_5_section_4.html
    >

    mmalc
  • on 1/12/08 3:39 PM, <wchild...> purportedly said:

    > I'm building a utility to take various types of data and parse them
    > according to my settings. I'm looking to have an introductory window
    > that asks what type of file the user wants to parse. Then based on
    > the response, I open the appropriate window to gather data about the
    > file to be handled. Separate interfaces will be used for the
    > different types of parsing operations.
    >
    > In the MVC paradigm, do you typically use a different controller for
    > each major interface? Should I have three controllers, one to handle
    > each type of parser? Three window controllers, to handle each major
    > settings interface?

    Not necessarily, if I understand your use of "interface". In the basic MVC
    implementation you have one model object to one controller to one or more
    views. More complex models may require multiple controllers. For instance,
    if one of your model properties is an array, you may need an
    NSArrayController to handle the array part, while an NSObjectController
    handles the other properties. Apple's recommendation of MVC may want you to
    have an intermediary controller (could be the one NSObjectController), but
    that doesn't always work well, I have found.

    Remember also that the MVC paradigm relates *only* to the GUI, so instead of
    looking at how you are parsing data, you would look at at how you will be
    displaying data.

    So the question to ask are, is the data created by the different parsing
    mechanisms different enough that they warrant being represented by different
    objects? Further, does each data object require a sufficiently different
    display that they warrant being displayed by different interfaces? If both
    of these are true, then your app probably requires one model object,
    controller, and window per file type.

    > What about nib files? I've read that putting everything in separate
    > nibs is more efficient in terms of loading time, but for quick and
    > dirty apps, it would be nice to be able to use the "one nib has all"
    > approach as well. Besides, this is not a time-critical app.

    Yes, what you have read is true. If you don't care about the load
    time--which means that you don't care whether your potential end users think
    your app sucks--then you don't need to be concerned about using only the
    main nib for the whole app.

    Best,

    Keary Suska
    Esoteritech, Inc.
    "Demystifying technology for your home or business"
  • On 12.01.2008, at 23:39, Daniel Child wrote:
    > I'm building a utility to take various types of data and parse them
    > according to my settings. I'm looking to have an introductory window
    > that asks what type of file the user wants to parse. Then based on
    > the response, I open the appropriate window to gather data about the
    > file to be handled. Separate interfaces will be used for the
    > different types of parsing operations.
    >
    > In the MVC paradigm, do you typically use a different controller for
    > each major interface? Should I have three controllers, one to handle
    > each type of parser? Three window controllers, to handle each major
    > settings interface?

      I do whatever 'feels best'. Generally, that means that I often
    wiggle along with dumping all in one file for simple projects, unless
    I know I'll want this to grow. If I know that my app will be bigger in
    the end, I generally break it up early on (generally, that means
    before this version ships, or if I know that this small version is
    just there because I want to ship a few intermediate releases before I
    get this feature completed, but my road map already has the bigger,
    more complex version on it).

      For the case you mention, it sounds like you could get away with a
    pair of controllers or so. The idea is that you have one (generic)
    class that encapsulates all the features that all the parsers expose
    to the GUI. The GUI, and any of its controllers, only know how to talk
    to this generic controller. The actual parsers would then be
    subclasses of this generic controller. Only the spot that opens the
    file would need to know what type of file it is, and would create the
    appropriate subclass.

      The rest of the app would just talk to the subclass through the
    generic controller's interface. If there is only one window, one
    window controller would be enough. If you only have very, very simple
    windows, and you don't open several instances of the same window, you
    may even get away without a window controller and just hide and show
    the windows as needed.

      Just saying that's possible. Having many controllers and many
    classes is a useful thing, if you can find the right boundaries to
    split your functionality at. When I'm not sure, I sometimes create one
    huge class until I see patterns developing, and then I split out small
    sub-controllers for the various parts until the main class has a
    manageable size again. If you split at the wrong boundaries, all you
    get is a icky mass of objects constantly looking at each other's
    variables or forwarding messages between each other. Forwarding
    messages is not unusual in an MVC design, but if you have too much of
    it, it becomes unmanageable.

      So, three window controllers don't sound like a bad idea at all. If
    you're new to this, I suggest just doing little prototypes that try
    different approaches and see which one works best for your problem
    domain. As someone else mentioned, few controllers means you'll have
    lots of switch statements or ifs looking at what object called you. If
    that's the case, you may want to split each "if" case out into its own
    controller. Whether that's a hand-rolled controller or a standard
    NSArrayController.

      You can have one big "master controller" that owns these window
    controllers (in document apps that's often the document, but in your
    case it could also be a class of your own, or your application
    delegate, or a helper object your app delegate talks to, or whatever
    makes sense and keeps your source files at a manageable size).

    Cheers,
    -- M. Uli Kusterer
    "The Witnesses of TeachText are everywhere..."
    http://www.zathras.de
  • On 12.01.2008, at 23:39, Daniel Child wrote:
    > I'm building a utility to take various types of data and parse them
    > according to my settings. I'm looking to have an introductory window
    > that asks what type of file the user wants to parse. Then based on
    > the response, I open the appropriate window to gather data about the
    > file to be handled. Separate interfaces will be used for the
    > different types of parsing operations.
    >
    > In the MVC paradigm, do you typically use a different controller for
    > each major interface? Should I have three controllers, one to handle
    > each type of parser? Three window controllers, to handle each major
    > settings interface?

    Look into the 'strategy' design pattern. All that you can do is have a
    single controller with appropriate
    strategy for each of the file type use different strategies
    dynamically for parsing them.

    http://en.wikipedia.org/wiki/Strategy_pattern

    I would propose a solution something like this:

    A  ParserController class. This will dynamically associate with a
    subclass of an abstract 'ParsingStrategy'
    class. Lets imagine that we are parsing an RTF, a DOC and  a PDF file.
    What I would have is  classes: RTFParsingStrategy,
    DOCParsingStrategy and PDFParsingStrategy - all are subclasses of
    ParsingStrategy. And each of these parsing strategies
    will associate with appropriate window controllers of their own to
    facilitate the necessary UI. I recommond having one window controller
    per window.  ParserController can also act as the window controller
    for your 'Entry UI'. The same can have intelligence to decide which
    strategy at runtime. This design makes it extremely flexible to add
    new strategies as you introduce new file types.

    Regards
    Shripada
  • On Jan 14, 2008, at 4:19 AM, Uli Kusterer wrote:
    > For the case you mention, it sounds like you could get away with a
    > pair of controllers or so. The idea is that you have one (generic)
    > class that encapsulates all the features that all the parsers
    > expose to the GUI. The GUI, and any of its controllers, only know
    > how to talk to this generic controller. The actual parsers would
    > then be subclasses of this generic controller. Only the spot that
    > opens the file would need to know what type of file it is, and
    > would create the appropriate subclass.
    I didn't think of subclassing from a "generic controller." I thought
    that the controllers are the least rewritable code, and therefore not
    generally subclassed. Now the model code for the different parsers...
    they have enough in common, I think, to justify subclassing.

    > The rest of the app would just talk to the subclass through the
    > generic controller's interface. If there is only one window, one
    > window controller would be enough. If you only have very, very
    > simple windows, and you don't open several instances of the same
    > window, you may even get away without a window controller and just
    > hide and show the windows as needed.
    I have been doing the latter, and am still trying to figure out what
    advantage there is to a window controller. What can it do that a
    regular controller can't, and vice versa....? I'm still failing to
    see their whole reason for being in non-document app cases.

    > You can have one big "master controller" that owns these window
    > controllers (in document apps that's often the document, but in
    > your case it could also be a class of your own, or your application
    > delegate, or a helper object your app delegate talks to, or
    > whatever makes sense and keeps your source files at a manageable
    > size).
    I'll give that a try too, once I figure out the window controllers.
    Thanks.
  • On Jan 16, 2008, at 12:40 AM, Daniel Child wrote:
    > I didn't think of subclassing from a "generic controller." I thought
    > that the controllers are the least rewritable code, and therefore
    > not generally subclassed. Now the model code for the different
    > parsers... they have enough in common, I think, to justify
    > subclassing.

    Well, in practice it is often the case that a controller isn't very
    reusable, but that's not a hard and fast rule. If your particular case
    allows for a certain amount of genericness, it would be a shame to let
    that opportunity go to waste and write special code over and over
    again. The main advantage of OOP is that it makes it easier to reuse
    code because it helps you structure it in reusable packages. But OOP,
    MVC and all the rest of the alphabet soup is there to serve you, not
    the other way round :-)

    >> The rest of the app would just talk to the subclass through the
    >> generic controller's interface. If there is only one window, one
    >> window controller would be enough. If you only have very, very
    >> simple windows, and you don't open several instances of the same
    >> window, you may even get away without a window controller and just
    >> hide and show the windows as needed.
    > I have been doing the latter, and am still trying to figure out what
    > advantage there is to a window controller. What can it do that a
    > regular controller can't, and vice versa....? I'm still failing to
    > see their whole reason for being in non-document app cases.

      The point is just that the window controller takes care of certain
    tasks for you. Of course, I can't think of a single one right now, but
    it does. I usually mainly use it together with NSDocument, so it'll
    probably come to me the moment I turn off the computer...

    Cheers,
    -- M. Uli Kusterer
    "The Witnesses of TeachText are everywhere..."
    http://www.zathras.de
  • On Jan 15, 2008, at 7:31 PM, Uli Kusterer wrote:

    > On Jan 16, 2008, at 12:40 AM, Daniel Child wrote:
    >> I didn't think of subclassing from a "generic controller." I
    >> thought that the controllers are the least rewritable code, and
    >> therefore not generally subclassed. Now the model code for the
    >> different parsers... they have enough in common, I think, to
    >> justify subclassing.
    >
    > Well, in practice it is often the case that a controller isn't very
    > reusable, but that's not a hard and fast rule. If your particular
    > case allows for a certain amount of genericness, it would be a shame
    > to let that opportunity go to waste and write special code over and
    > over again. The main advantage of OOP is that it makes it easier to
    > reuse code because it helps you structure it in reusable packages.
    > But OOP, MVC and all the rest of the alphabet soup is there to serve
    > you, not the other way round :-)

    For what I do, subclassing controllers was the way to go.  In my full-
    screen app, each of my "screens" is represented by a nib containing
    the UI.  The nib's owner is then a subclass of IIScreenController.
    The base class has quite a bit of stuff in there.  For example,
    building up a language model for speech recog for the current screen
    by walking the custom UI and looking at everything that implements my
    IISpeakable protocol.  No code was necessary in any subclass for
    speech recog.

    Some subclasses contain very little code, especially for those screens
    where bindings could be used for 100% of the implementation.  In other
    cases, there's large amounts of custom code which deals with the
    unique business logic for a particular screen.

    My screen-loading code is then in my main app controller.  There, I
    load screens via names which can be built up dynamically (no need to
    maintain say a massive switch block).  Thus, every time I need to add
    a new screen, I just create a well-named nib and controller subclass.
    Code to move to a new screen is simply [self
    pushScreen:@"MyNewScreenName" parameters:aDictionary].  And, I can
    really drop that code anywhere.  Thus, if I want to provide a link to
    "ScreenB" from two or more places, I can do that with just one line of
    code.  I pass parameters from screen to screen using a dictionary.
    Thus, there was no need to implement custom API entry points with
    varying parameters in each subclass.  There's only a single API entry
    point that just takes a dictionary.

    Just wanted to add that last paragraph to also show that you can write
    your code to be extremely extensible with very little effort.  In past
    frameworks, I've often had to write extra code to "wire in" any new
    subclass I would create.  And, going back to the speech-recog example,
    as I add/edit new UI elements, I can simply set their speakable*
    property in IB (phrase to use) and I'll end up with a properly built
    language-model at runtime.  No code to write; very extensible and
    maintainable.

    * No such property yet exists for Aqua controls; all my UI is custom
    and therefore I created IB Plug-ins to edit them.

    ___________________________________________________________
    Ricky A. Sharp        mailto:<rsharp...>
    Instant Interactive(tm)  http://www.instantinteractive.com
  • On Jan 15, 2008, at 5:40 PM, Daniel Child wrote:

    > On Jan 14, 2008, at 4:19 AM, Uli Kusterer wrote:
    >> The rest of the app would just talk to the subclass through the
    >> generic controller's interface. If there is only one window, one
    >> window controller would be enough. If you only have very, very
    >> simple windows, and you don't open several instances of the same
    >> window, you may even get away without a window controller and just
    >> hide and show the windows as needed.
    > I have been doing the latter, and am still trying to figure out what
    > advantage there is to a window controller. What can it do that a
    > regular controller can't, and vice versa....? I'm still failing to
    > see their whole reason for being in non-document app cases.

    The main advantage of using NSWindowController in a non-document app
    is management of the top-level objects of your nib.

    http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/Articl
    es/MemMgmtNibObjects.html


    Something which is not documented on the above page is that bindings
    often cause retain cycles among nib objects.  For example, if a
    control in the window is bound to or through a property of the File's
    Owner, then the File's Owner is implicitly retained.  As a
    consequence, it becomes difficult to properly release the owner and
    all of the nib's objects.  Since 10.4, NSWindowController has built-in
    smarts for breaking that retain cycle.

    For a nib which contains a standalone view (not contained in a
    window), 10.5 introduces NSViewController whose purpose is roughly the
    same.  See:

    http://developer.apple.com/releasenotes/Cocoa/AppKit.html#NSViewController

    Regards,
    Ken Thomases
previous month january 2008 next month
MTWTFSS
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
Go to today