http://www.perlmonks.org?node_id=109773


in reply to Seeking MVC Wisdom

MVC is actually quite simple. What complicates discussions of it with respect to old Smalltalk systems is that it was tied up into the UI paradigm of the time. You have three actors in typical MVC: Many newer UI systems based on windowing systems merge the view and controller into a single widget. So the C in MVC is mostly not useful. This is why (for instance) the Observer pattern in Design Patterns only has two participants (once you get past the C++ inheritance crap). The important idea is this: the model notifies views when it changes. The views then can update themselves as needed. The easiest implementation of this is to have each model keep a list of views. Upon a change, the model sends a message to each of the views saying that it's changed. Some systems include an indication of what has changed.

package Model; # mix in to model classes that are # implemented as blessed hashes # This is called by a View sub addDependent { my $self = shift; my $dependent = shift; my $dependents = (self->{dependents} ||= []); push @$dependents, $dependent; } # This is called by a View sub removeDependent { my $self = shift; my $dependent = shift; my $dependents = $self->{dependents} || return; @$dependents = grep { $_ != $dependent } @$dependents; } # This is called by the Model # you can pass additional data as needed sub _changed { my $self = shift; my $dependents = $self->{dependents} || return; foreach my $dependent ( @$dependents ) { $dependent->update($self, @_); } } package View; # mix in to observer classes of any kind sub update # stub: do nothing { my ($self, $model, @aspectData) = @_; }
Then this gets used like this (in a Model class):

package MyModel; @MyModel::ISA = qw(SomethingElse Model); sub changeSomething { my $self = shift; my $value = shift; $self->{something} = $value; $self->_changed('something', $value); } package MyView; sub update { my ($self, $model, $aspect, $otherStuff) = @_; # hey! $model has changed its $aspect! } package main; my $view = bless {}, 'MyView'; my $model = bless {}, 'MyModel'; $model->addDependent($view); # now the following # calls $view->update($model, 'something', 123); $model->changeSomething(123);
The passing of the new value is an optimzation, and is not strictly necessary.

update: added more sample code

Replies are listed 'Best First'.
Re: Re: Seeking MVC Wisdom
by coreolyn (Parson) on Sep 04, 2001 at 17:20 UTC

    Man I had to be AFK for a bit and I finally got back to this node -- and the lightbulb is finally lit! Man this is an awesome site -- thanks all :)

    coreolyn