MVC question about updating the Model

  • I'm having a problem deciding on how a Model object should be updated.

    I have multiple resource objects that are represented in an
    NSOutlineView. These resource objects can be updated by their own
    triggered timer or potentially on demand by the user via the View (a
    button is clicked in the UI).

    At first, I thought that the resource object should have the
    capability to update itself. Therefore, the resource has a method like
    so:

    [resource update];

    If the resource's timer fires, it calls it's update method like so:

    [self update];

    If the resource update button is clicked by the user, the selected
    resource item is updated by the NSWindowController with:

    [resource update];

    This is where I'm having difficulty determining what should be
    standard practice. Would it be better to post a notification that
    indicates the resource should update itself? Or is it good enough to
    leave it as is?

    One other approach I've considered is whether the Model should have
    the ability to update itself at all. Should the controller be
    responsible for updating the resource always?

    It seems that either approach is viable, but which is better?

    -Matt
  • Hi Matt

    > I have multiple resource objects that are represented in an
    > NSOutlineView. These resource objects can be updated by their own
    > triggered timer or potentially on demand by the user via the View (a
    > button is clicked in the UI).
    >
    > At first, I thought that the resource object should have the
    > capability to update itself. Therefore, the resource has a method like
    > so:
    >
    > [resource update];
    >
    > If the resource's timer fires, it calls it's update method like so:
    >
    > [self update];
    >
    > If the resource update button is clicked by the user, the selected
    > resource item is updated by the NSWindowController with:
    >
    > [resource update];
    >
    > This is where I'm having difficulty determining what should be
    > standard practice. Would it be better to post a notification that
    > indicates the resource should update itself? Or is it good enough to
    > leave it as is?
    >
    > One other approach I've considered is whether the Model should have
    > the ability to update itself at all. Should the controller be
    > responsible for updating the resource always?
    >
    > It seems that either approach is viable, but which is better?

    When designing an OO system, the guiding principle should always be "Responsibility Driven Design".

    In other words, what determines when the resource should be updated? If the resource can be responsible for keeping itself updated, then that is where the update method belongs and it can be called from an internal timer method, if that is the only way to "detect" the new state.

    If the resource doesn't know how to update itself, then the update method can be called from any other code, including a controller.

    My guess is that you have a resource that know how to update its state and that change in state is observed by the controller/UI. However, you also want to be able to provide a user with an update button, in case they want to ensure that the state is up to date between automatic refreshes. In which case, the controller handles the action of the button and calls the update method on the resource.

    Joanna

    --
    Joanna Carter
    Carter Consulting
  • On 16/04/2010, at 11:30 PM, Matt DeFoor wrote:

    > One other approach I've considered is whether the Model should have
    > the ability to update itself at all. Should the controller be
    > responsible for updating the resource always?

    No, because if another controller is able to affect the model, the update won't get noticed.

    The resource should keep track of WHEN an update is required, but it should not make any assumptions about HOW the update is actually accomplished. It can do that using classic notifications or KVO. The controller(s) can receive those notifications and translate them into the required actions on the view(s) they control to get the update performed.

    Also, having a manual refresh button should be unnecessary - if your resource is always able to flag an update whenever a change in its state occurs, then there is no possibility that the view and the model will get out of step.

    --Graham
  • On Apr 16, 2010, at 06:30, Matt DeFoor wrote:

    > This is where I'm having difficulty determining what should be
    > standard practice. Would it be better to post a notification that
    > indicates the resource should update itself? Or is it good enough to
    > leave it as is?
    >
    > One other approach I've considered is whether the Model should have
    > the ability to update itself at all. Should the controller be
    > responsible for updating the resource always?

    I think your original approach is just fine.

    You've encapsulated the "how" of updating your data model in the data model itself, which seems correct, and you just had to decide the mechanism of "when".

    For manual updates initiated from the UI, your data model must have a public "update" method that is called by the window controller from the relevant button's action method. (Or, say, from an equivalent menu item hooked up to the same action method.)

    For timed updates, you seem to have a choice of putting the timer in your data model, or putting the timer in your window controller. One good way to decide this is to ask yourself this question:

    If I were to have *two* windows and window controllers showing this information, would I want to have a separate timer in each controller?

    With the limited information you've given us, the answers seems to be "no". You'd probably want both windows to show updated information on the same schedule. Therefore, the auto-update timer needs to be in the data model itself.

    If, on the other hand, the requirements of your application would dictate separate timers per window, then the timers need to be in the window controllers.
  • On Fri, Apr 16, 2010 at 10:51 AM, Quincey Morris
    <quinceymorris...> wrote:
    > For timed updates, you seem to have a choice of putting the timer in your data model, or putting the timer in your window controller. One good way to decide this is to ask yourself this question:

    And this is when I become a fan of splitting the "model" layer into a
    "model object" layer and a "model controller" layer. The "model
    object" layer just contains a bunch of bags-o-data. In simple
    applications this might be a few NSDictionaries; in more complicated
    apps it might be a Core Data object graph. But the objects themselves
    are concerned only with storing and retrieving data associated with
    themselves; maybe some simple validation like "this property can't be
    null" or "only one of these two properties can be set."

    But the real business logic would live in the "model controller"
    layer, which deals with entire graphs of model objects. This is really
    where the heavy lifting goes; things like saving/loading,
    calculations, or even periodic updates. It stores the results of these
    sorts of operations inside the dumb-bags-of-data. It's this layer that
    the view-controllers like NSWindowController or NSViewController talk
    to.

    --Kyle Sluder
  • On Apr 16, 2010, at 11:00, Kyle Sluder wrote:

    > And this is when I become a fan of splitting the "model" layer into a
    > "model object" layer and a "model controller" layer.

    I think that in this case, if the auto-updating can *safely and correctly* be encapsulated within a single object, then it's preferable and simpler just to do so.

    However, I think I'd agree even in this case, that a public [myModel updateResources] method is preferable to [[myModel someParticularObject] updateResources], so that it's a private implementation detail precisely where in the model the update is done. That would be a small but very appropriate use of the Sluder Splitting Principle.
  • On Fri, Apr 16, 2010 at 11:24 AM, Quincey Morris
    <quinceymorris...> wrote:
    > I think that in this case, if the auto-updating can *safely and correctly* be encapsulated within a single object, then it's preferable and simpler just to do so.

    This is true, but it does depend on your definition of "safely and
    correctly," which of course can vary over time. One of the reasons I
    like to split my models is because a self-contained collection of
    model objects is a lot easier to split off into a framework and
    compile into other apps—or even other architectures. Very helpful when
    you are porting all of your applications to a new shiny platform (in
    this example, the performance characteristics of NSTimer might differ
    sufficiently to warrant its replacement), or even just writing an
    importer for one of your other apps.

    But of course at some point you need to stop worrying about making
    your code portable and just sit down and write the code. :)

    --Kyle Sluder
previous month april 2010 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    
Go to today