Barry Hoggard writes:
> Do you have a favorite approach for writing the Model objects?

One solution is to create an interface for accessors, i.e. "get",
which the views call on objects they need to access.  Our controller
and model objects share this same "accessor" interface, which allows
the views to access control and database values the same way.

For example,

  vs_form_field('UserAccountForm.RealmOwner.name', {},
    [['->get_request'], 'task_id', '->equals_by_name', 'USER_ACCOUNT_CREATE'])

The first parameter to vs_form_field identifies the RealmOwner.name
field of FormModel UserAccountForm.  The second parameter contains
optional attributes.  The third param defines a conditional which
says: only display this row if the view is being rendered in the
USER_ACCOUNT_CREATE task.  We use the same view in the user account
register and edit tasks.

The view doesn't allow you to change your User ID in edit mode.  The
business logic doesn't allow edits either, but you still have to
control the visible state.  You could do that with a model, but that's
denormalization.  Rather than copying state, we go directly to the
source, the request object.  The Request is not a "model", but an
ordinary Perl object, which implements the WidgetValueSource
interface.

Originally, we didn't have this clear separation of WidgetValueSource
and Model.  That change really helped us in the view code.  There are
other WidgetValueSource objects (formatters, icons, etc.) and the
views access the data in the same way.

Perhaps you can accomplish this with hash references, but I find that
involves a lot of copying.  Having a method call to an object allows
the object to control the behavior, e.g. dynamically computing
values.  Not coupling it to a heavier Model interface gives you a lot
of flexibility.  For the most part, all the views want is the values.

Rob

P.S. Nice to meet you, Barry.


Reply via email to