Re: Action based undo or snapshot based undo? Summary!
Re: Action based undo or snapshot based undo? Summary!
- Subject: Re: Action based undo or snapshot based undo? Summary!
- From: Greg Titus <email@hidden>
- Date: Thu, 6 Feb 2003 08:56:15 -0800
On Thursday, February 6, 2003, at 03:10 AM, Alexander Lamb wrote:
However, I think we could go further in the notification of change
patterns.
Firstly, the post notification and the undo management are so
"generic" in
the model, why not suggest having a generic superclass to handle those
things (like EOGenericRecord in EOF in a way)? Then, the notifications
could
become more standard and could be all named "attribute update" for
example
and the object passed with the notification could contain: the
document, the
object being modified, the attribute name.
Depending upon what your model objects looks like, this can make a lot
of sense. You could put your notification and undo management into
key-value coding and handle them automatically:
- (void)takeValue:(id)value forKey:(NSString *)aKey;
{
[[[self undoManager] prepareWithInvocationTarget:self] takeValue:[self
valueForKey:aKey] forKey:aKey];
[super takeValue:value forKey:aKey];
[[NSNotificationCenter defaultCenter]
postNotificationName:@"ObjectDidChange" object:self];
}
... if you are sure that you use key-value coding instead of direct
accessors everywhere that you change your model objects.
Often it is just as easy to update every piece of UI for a model object
when the model object changes, rather than making sure to write all the
logic to change all the correct UI for each different type of attribute
change, but that's up to the specific model and application. (And how
much work you want to do or need to do to minimize unnecessary UI
updates.)
It will also often turn out to be very common to change many related
objects or many related attributes in the same event, so it can be a
big efficiency win to coalesce notifications so that your controllers
and UI don't need to do more work dealing with intermediate states of
the model objects. I.e. set up a structure where you can delay
notifications. Instead of notifying on every attribute change, mark the
object as "hasChanges" and then post-process your model at the end of
the event and have every changed object send a single notification then.
And... To make it even more generic, create an association class that
is
instantiated for each UI object that needs to either be updated or that
changes the value of an object (again, more or less on the model of
EOF).
This association objects listen to "attribute update" and decide if
they
need to update the given UI object they monitor. In that way, the
controler
code becomes even simpler since you don't need to listen to
notifications,
but simply create association objects upon initialisation. To go even
further, as in EOF (my obsession as you can see:-), have the
associations
classes as a palette in IB. Since there is no EOModel, simply have the
inspector of the association display a text field where the name of the
attribute would be entered.
Don't forget display groups.... you need to know which are the selected
objects whose changes should be reflected in the UI. And writing the
controller code for a specific UI object is about the same amount of
code and much easier for a beginner to understand than writing an
association class that does the same thing. So it doesn't really save
you work unless you reuse UI elements in more than one place.
I think you are absolutely right that associations and display groups
are incredibly useful ideas and are a great way to set up a UI with IB.
A bunch of us tried to convince NeXT/Apple for a long time to chop
EOInterface out of EOF and give it to the AppKit team to use with all
applications.
But it isn't an easy set of code to write. And it does have its own
drawbacks.
For instance, enabling/disabling appropriate UI controls for the
current state. In EOF apps, if you use associations to enable/disable
UI, then you need to have the logic for that exposed as an attribute in
your model for your association to hook up to. But often that is logic
that is really external to the model itself and should be in the
controller layer instead. This is an example of how using associations
tends to 'squeeze' your controller layer. It encourages you to put more
code in the model or in the UI and avoid putting code in the
controller, so that your controller layer basically ends up being the
series of association connections in IB and that is pretty much all.
That works really well for database apps. There isn't usually a whole
lot of interrelationships between attributes or complicated logic in
the controller. "This field is displayed here, this other field is
displayed there" can be most of the controller work in a database app.
Associations shine for this. But the more interrelationships you have,
the more display preferences you have for displaying things differently
even though the model doesn't change, the more complex views you
have... the more difficult it is to shoehorn what you want to do into
an association model. You can always write more different types of
associations, but it stops being the most straightforward way to do
things.
Again, it all depends on your app. If you have a lot of similar UI and
similar control structures for a lot of different windows, then writing
generic association style connections between model and view can be a
big win. If not (and it is usually not), then writing your own
controller logic for catching notifications and updating UI is more
straightforward and not really any more code.
-- Greg
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.