Search code examples
model-view-controllerviewmodelobserver-pattern

How does the model update the view in MVC pattern?


I have a confusion about the structure of MVC pattern.

In some places while searching on google I found that the model updates all those views which are subscribed to that model. How the model updates the view in MVC pattern?

Can anyone give me a simple and clear idea how this happen by giving an example?

Thanks


Solution

  • MVC comes in a variety of flavours. It sounds like you may have been reading about the supervising controller pattern in which the view observes on changes to the model.

    I see from your past questions and answers you like php. I'm not sure how common the supervising presenter is in php (I've certainly never used it, but am interested to know if others do). It is common in .Net applications (eg winforms) where a model can be databound to a UI control. The view is notified of changes to the model by subscribing to model events.

    Anyhow, because I thought this would be fun to try in php I put together an example:

    <?php
    
    $input = array(2, 3, 4, 5, 6, 7, 8, 9, 10);
    
    $model = new model(1);
    $controller = new controller(
                  $model, new view($model, 0), new view($model, 2)
                  );
    
    $controller->doAction($input);
    
    class model {
      //the model changed event
      public $modelChangedEvent = array();
      private $val;
    
      public function __construct($val) {
         $this->val = $val;
      }
    
      public function setVal($val) {
         $this->val = $val;
         //raise the model changed event because the model state has changed
         $this->raiseModelChangedEvent();
      }
    
      public function getSquaredVal() {
         return pow($this->val, 2);
      }
    
      private function raiseModelChangedEvent() {
         foreach ($this->modelChangedEvent as $handler)
            call_user_func($handler);
      }
    
    }
    
    class view {
    
      private $model;
      private $decimalPlaces;
      private $valueHistory = array();
    
      public function __construct($model, $decimalPlaces) {
        $this->model = $model;
        $this->valueHistory[] = $model->getSquaredVal();
        $this->decimalPlaces = $decimalPlaces;
        //listen to the model changed event and call handler
        $this->model->modelChangedEvent[] = array(
                                 $this,
                                 'modelChangedEventHandler'
                                  );
      }
    
      public function showView() {
        $formatted = array_map(
                     array($this, 'getFormattedValue'), $this->valueHistory
                     );
        echo implode('<br/>', $formatted), '<br/><br/>';
      }
    
      public function modelChangedEventHandler() {
         $this->valueHistory[] = $this->model->getSquaredVal();
      }
    
      private function getFormattedValue($val) {
         return number_format($val, $this->decimalPlaces);
      }
    
    }
    
    class controller {
    
       private $model;
       private $view1;
       private $view2;
    
       public function __construct($model, $view1, $view2) {
         $this->model = $model;
         $this->view1 = $view1;
         $this->view2 = $view2;
       }
    
       public function doAction($input) {
         foreach ($input as $val) $this->model->setVal($val);
         $this->view1->showView();
         $this->view2->showView();
       }
    
    }
    ?>