Page 8 of 9
Posted: Thu Jul 05, 2007 7:39 pm
by Christopher
BDKR wrote:What I do is kind of an MVCC approach. One controller is specifically for Views and the other controller is for logic. The controllers themselves don't have any actual code other then the name of a method or function that will take care of the requested operation. The logic controller is allways interogated first in advance of any output of markup. The view controller is then pased the output from whichever logic operation was run.
I'll try to hack out some simple example code later if that doesn't make any sense.
Yes, I think code would helpful. I like how you struggle with the separation of View and Controller by creating a "view controller" to fill in the grey area. It is a great example if the difficulty of View/Controller separation and gives me an insight into one rule we might want to follow in defining next-gen frameworks:
Goal: The framework must support drawing the line of VC separation anywhere between the View and Controller.
Posted: Thu Jul 05, 2007 7:39 pm
by Christopher
d11wtq wrote:Indeed, it's common that in your controller you'll just push data into properties, or through a method which acts as a transport to get the data to the template. I do this myself using __get() and __set(), then building variable-variables before including the template file. I've seen this approach more than once before too.
I believe that what you are describing is using the Controller as what I have heard called a View Helper or View Model. I would like to get to the point were we are all using common terms.
Concept: The View gets it data from the Controller which acts as a View Helper or View Model.
d11wtq wrote:I go as far as building interfaces and abstracts for "Viewable" components (page templates and view helpers). All these do pretty much is act as a container for variables (model data) which will appear visible in the template files. The controller holds an instance of the view, pushes variables into it, then asks the view to "render" itself. View::render() just iterates over all the variables it collected through View::setVar(), creates $$variables, then include()'s the template file. There is a clear coupling between the controller and the view though so arguably it's pointless having the two classes:
There is clear coupling between the View and Controller if you follow your "The controller holds an instance of the view, pushes variables into it, then asks the view to "render" itself." That is the concept described about. However it is not the only way. Certainly the Controller can both pass the Model to the View with no data in the Controller, and the View could instantiate the Model itself with no Controller involvement.
Concept: The View gets it data from the Model which is passed to it by the Controller
Concept: The View gets it data from the Model which it gets/instantiates itself
d11wtq wrote:Back to the example code posted, I'm not folowing it too well. Who decides what $model should be passed to the constructor

Surely that's the controller's job to pull in Model itself? Maybe the view needs more than one model too. The code almost suggests that each page has a known model.... this goes very much against the way I think MVC should work. Controller holds a great deal of responsibility for everything that happens so making Controller too tightly coupled to anything else just reduces flexibility IMHO.
Your core question is: who knows how to find the Model? That is the one of the most confusing parts of MVC. In the three concepts above we get three answers:
1. The Controller knows the Model because it is the Model
2. The Controller knows the Model. The Controller probably uses the same conventions that it uses to know the View, so it creates both and gives the Model to the View. This seems to lend itself to some sort of convention based Model-View association.
3. The View knows the Model. This seems to lend itself to the programmer being able to define which Model(s) go with a View.
That leads me to:
Goal: The framework must support many types of MV associations.
Posted: Thu Jul 05, 2007 7:39 pm
by Christopher
kyberfabrikken wrote:This is where a separate assembly layer comes in. The controller "decides" which model components it needs - so to speak - in the assembly layer. A simple, yet powerful, solution, is to pass the dependencies in the constructor, and encapsulate the creation in a factory. This factory can be put in a common assembler, with factories for all your applications objects. Such an assembler is called a service locator, a registry or a dependency injection container, depending on how it's implemented.
I think kyberfabrikken is trying to make it easier to create Models via a ServiceLocator/Registry/DI. That ease and flexibility makes is possible for Models to be created in either/both the Controller or View using the same mechanism. That sounds like a win.
Goal: Use ServiceLocator/Registry/DI so Models can be created by the Controller or View using the same mechanism
Posted: Fri Jul 06, 2007 3:20 am
by Chris Corbyn
I'd be interested to see a really simplistic example of using DI. To be honest, I need to research DI...
Posted: Fri Jul 06, 2007 3:52 am
by stereofrog
Here you are, sir
Code: Select all
class Di {
function get($ident) {
if(isset($this->$ident))
$ident = $this->$ident;
if(!class_exists($ident))
return $ident;
$class = new ReflectionClass($ident);
$ctor = $class->getConstructor();
if(!$ctor)
return $class->newInstance();
$params = array();
foreach($ctor->getParameters() as $p)
$params[] = $this->get($p->name);
return $class->newInstanceArgs($params);
}
}
example
Code: Select all
class Db {
function __construct($dsn) {$this->dsn = $dsn;}}
class Model {
function __construct($db) { $this->connection = $db; }}
class View {
function __construct($template_dir) { $this->templates = $template_dir; }}
class Controller {
function __construct($model, $view) {
$this->myModel = $model;
$this->myView = $view;
}}
$di = new Di;
$di->dsn = "mysql://";
$di->template_dir = '/home';
$cc = $di->get('Controller');
var_dump($cc);
Wow, it works, even with zero configuration! Now let's replace one of the classes:
Code: Select all
class OtherView {}
$di->view = 'OtherView';
$cc = $di->get('Controller');
var_dump($cc);
see also
http://sourceforge.net/projects/phemto for a not that simplistic example.
ed: forgot class definitions first time
Posted: Fri Jul 06, 2007 4:27 am
by Maugrim_The_Reaper
There is clear coupling between the View and Controller if you follow your "The controller holds an instance of the view, pushes variables into it, then asks the view to "render" itself." That is the concept described about. However it is not the only way. Certainly the Controller can both pass the Model to the View with no data in the Controller, and the View could instantiate the Model itself with no Controller involvement.
I don't think its necessarily coupling (or at least not high coupling). With the V and C occupying the Presentation Layer there'll always be some interaction between both unless there a third spoke to the wheel acting as an intermediary.
I really agree on getting a common terminology and avoiding the misuse of established terms. I think I've had my fill of "Two-Step View" on the Zend Framework already...
Concept: The View gets it data from the Model which is passed to it by the Controller
Concept: The View gets it data from the Model which it gets/instantiates itself
I usually call this the View-Model-Push and View-Model-Pull decision. Ad-hoc terms all

. The View-Model-Pull is captured by the View Helper Pattern (J2EE Design Pattern), but isn't a formal pattern in other references as such. I guess the Pattern really just declares an obvious implementation of the read-only link implicit in MVC between the View and Model.
I'm not aware of any formal term for the first concept above. I think it's almost taken for granted that something passes a Model to the View once its instantiated.
Your core question is: who knows how to find the Model? That is the one of the most confusing parts of MVC. In the three concepts above we get three answers:
1. The Controller knows the Model because it is the Model
2. The Controller knows the Model. The Controller probably uses the same conventions that it uses to know the View, so it creates both and gives the Model to the View. This seems to lend itself to some sort of convention based Model-View association.
3. The View knows the Model. This seems to lend itself to the programmer being able to define which Model(s) go with a View.
That leads me to:
Goal: The framework must support many types of MV associations.
Should edit "the Model" to "a Model". Unless there some really tight coupling, or the Controller is utilised at the arbitor of all Model interaction, the View in many cases will need additional Models the Controller is not aware of upfront.
To take a real life example, myself and Ralph Schindler (the ZF thing again) disagree on a few points. The result is that Ralph has created Zend_Layout - a class which relies on the dispatching of multiple Controllers in order to render multiple Views which are built into a composite output tree (and their required Models). My opposing approach, Zend_View Enhanced, completely ignores the Model under the assumption a user is capable of using View Helpers to "pull" a Model into a View mid-rendering.
I disagree with the first statement. The Controller is not the Model. The Controller may "control" the Model but the Model itself should be responsible for it's own conduct. That's the main difference between another stress line in MVC - when you have a Fat Controller (say something like Model validation and aggregation), is it time to put it on a diet and transfer the Fatness to the Model where it usually belongs?
Posted: Fri Jul 06, 2007 4:27 am
by Chris Corbyn
Nice one, thanks for that. I've read it a few times and I'm still reading it
/me sips on coffee for another read
Posted: Fri Jul 06, 2007 6:05 am
by Christopher
Maugrim_The_Reaper wrote:There is clear coupling between the View and Controller if you follow your "The controller holds an instance of the view, pushes variables into it, then asks the view to "render" itself." That is the concept described about. However it is not the only way. Certainly the Controller can both pass the Model to the View with no data in the Controller, and the View could instantiate the Model itself with no Controller involvement.
I don't think its necessarily coupling (or at least not high coupling). With the V and C occupying the Presentation Layer there'll always be some interaction between both unless there a third spoke to the wheel acting as an intermediary.
You are right, coupling is not the right word here. I was responding to d11wtg's comment that "
There is a clear coupling between the controller and the view though so arguably it's pointless having the two classes" by giving examples of other View/Controller arrangements -- with looser coupling.
Maugrim_The_Reaper wrote:I really agree on getting a common terminology and avoiding the misuse of established terms. I think I've had my fill of "Two-Step View" on the Zend Framework already...
Concept: The View gets it data from the Model which is passed to it by the Controller
Concept: The View gets it data from the Model which it gets/instantiates itself
I usually call this the View-Model-Push and View-Model-Pull decision. Ad-hoc terms all

. The View-Model-Pull is captured by the View Helper Pattern (J2EE Design Pattern), but isn't a formal pattern in other references as such. I guess the Pattern really just declares an obvious implementation of the read-only link implicit in MVC between the View and Model.
I'm not aware of any formal term for the first concept above. I think it's almost taken for granted that something passes a Model to the View once its instantiated.
I like where you are going with the names, maybe Controller-Model-Push and View-Model-Pull would be less confusing. The first concept is where there is essentially no Controller/View separation.
Maugrim_The_Reaper wrote:Your core question is: who knows how to find the Model? That is the one of the most confusing parts of MVC. In the three concepts above we get three answers:
1. The Controller knows the Model because it is the Model
2. The Controller knows the Model. The Controller probably uses the same conventions that it uses to know the View, so it creates both and gives the Model to the View. This seems to lend itself to some sort of convention based Model-View association.
3. The View knows the Model. This seems to lend itself to the programmer being able to define which Model(s) go with a View.
That leads me to:
Goal: The framework must support many types of MV associations.
Should edit "the Model" to "a Model". Unless there some really tight coupling, or the Controller is utilised at the arbitor of all Model interaction, the View in many cases will need additional Models the Controller is not aware of upfront.
Yeah it should be clearer that there can be multiple models. My main point here was that they are different styles. Controller-Model-Push is more automated and convenient, but perhaps less flexible. View-Model-Pull you an pick-and-choose Models from anywhere you want.
Maugrim_The_Reaper wrote:To take a real life example, myself and Ralph Schindler (the ZF thing again) disagree on a few points. The result is that Ralph has created Zend_Layout - a class which relies on the dispatching of multiple Controllers in order to render multiple Views which are built into a composite output tree (and their required Models). My opposing approach, Zend_View Enhanced, completely ignores the Model under the assumption a user is capable of using View Helpers to "pull" a Model into a View mid-rendering.
My position is that both you and Ralph are providing solutions, instead of proposing a base MVC architecture on which you can support all the above. Sometimes you need hierarchical Controllers. Sometimes you need hierarchical Views. Sometimes you need simple Views. Sometimes you need the convenience of Controller-Model-Push. Other times you need the flexibility of View-Model-Pull (with View Helpers or via Controller automation). That's where I was going in our previous discussion.
Maugrim_The_Reaper wrote:I disagree with the first statement. The Controller is not the Model. The Controller may "control" the Model but the Model itself should be responsible for it's own conduct. That's the main difference between another stress line in MVC - when you have a Fat Controller (say something like Model validation and aggregation), is it time to put it on a diet and transfer the Fatness to the Model where it usually belongs?
I was describing the case where the View and Controller are combined into a single Presentation class. In that case the Controller essentially acts as a View Helper for the View.
Posted: Fri Jul 06, 2007 7:00 am
by sike
arborint wrote:Maugrim_The_Reaper wrote:I really agree on getting a common terminology and avoiding the misuse of established terms. I think I've had my fill of "Two-Step View" on the Zend Framework already...
Concept: The View gets it data from the Model which is passed to it by the Controller
Concept: The View gets it data from the Model which it gets/instantiates itself
I usually call this the View-Model-Push and View-Model-Pull decision. Ad-hoc terms all

. The View-Model-Pull is captured by the View Helper Pattern (J2EE Design Pattern), but isn't a formal pattern in other references as such. I guess the Pattern really just declares an obvious implementation of the read-only link implicit in MVC between the View and Model.
I'm not aware of any formal term for the first concept above. I think it's almost taken for granted that something passes a Model to the View once its instantiated.
I like where you are going with the names, maybe Controller-Model-Push and View-Model-Pull would be less confusing. The first concept is where there is essentially no Controller/View separation.
i just name them push or pull views ( templates way back in time (: ) - regardless of who is pushing or pulled from
chris
Posted: Fri Jul 06, 2007 11:40 am
by Maugrim_The_Reaper
My position is that both you and Ralph are providing solutions, instead of proposing a base MVC architecture on which you can support all the above. Sometimes you need hierarchical Controllers. Sometimes you need hierarchical Views. Sometimes you need simple Views. Sometimes you need the convenience of Controller-Model-Push. Other times you need the flexibility of View-Model-Pull (with View Helpers or via Controller automation). That's where I was going in our previous discussion.
The debate will roll on

. I don't disagree, but I've argued enough times on the lists and IRC to know the current View implementation isn't going anywhere so we're stuck with patching over the flaws. The nature of the patching is still in doubt - Ralph is busy cloning Zend_View Enhanced as we speak into a funky specialised set of helpers. Never seen a guy so committed to the downfall of my ideas before...
I was describing the case where the View and Controller are combined into a single Presentation class. In that case the Controller essentially acts as a View Helper for the View.
Sorry - I thought you meant something else entirely.
Posted: Fri Jul 06, 2007 12:00 pm
by Christopher
Maugrim_The_Reaper wrote:The debate will roll on

. I don't disagree, but I've argued enough times on the lists and IRC to know the current View implementation isn't going anywhere so we're stuck with patching over the flaws. The nature of the patching is still in doubt - Ralph is busy cloning Zend_View Enhanced as we speak into a funky specialised set of helpers. Never seen a guy so committed to the downfall of my ideas before...
My earlier proposal was that Zend_View_Enhanced should be a drop-in replacement for the current Zend_View that builds in infrastructure for doing Views right. On top of that, your current enhanced functionality could be the first implementation on top of that. Ralph's layout style stuff could be build too. The problem now is that Ralph sees you solution as competition for his solution getting implemented. That competing proposal dynamic is the core problem with the Zend Framework. It produces the hodge-podge that we now have. It's a little better than PEAR I guess, but still the same flawed propose/accept/assimilate system.
Posted: Fri Jul 06, 2007 3:23 pm
by kyberfabrikken
d11wtq wrote:Nice one, thanks for that. I've read it a few times and I'm still reading it :oops:
Here's an even simpler one for you:
Code: Select all
class Locator
{
protected $instances = Array();
/**
* Returns a singleton instance of a class.
*/
function get($className) {
$className = strtolower($className);
if (!isset($this->instances[$className])) {
$factoryName = 'create' . $className;
$this->instances[$className] = $this->$factoryName();
}
return $this->instances[$className];
}
function createPeopleGateway() {
return new PeopleGateway($this->get('DatabaseConnection'));
}
function createDatabaseConnection() {
return new PDO("mysql=localhost;dbname=foo", "root");
}
}
// usage
$locator = new Locator();
$people = $locator->get('PeopleGateway');
$people->getPerson(42);
As you can see, this is a bit hand crafted. A DI container relies on configuration (Usually using Interfaces) to automate the factories, so that you don't need to write each factory by hand. The basic idea is the same though: Take a registry, and fit it with factories to create instances on the fly.
There's an evolved version of the above code at:
http://svn.sourceforge.net/viewvc/konst ... iew=markup
http://svn.sourceforge.net/viewvc/konst ... iew=markup
It's part of the Konstrukt framework, but it has no dependencies, so it can be used separately.
Posted: Fri Jul 06, 2007 6:24 pm
by Christopher
Here's one that combines a loader and registry. I find it handy to inject those to capabilities together.
Code: Select all
<?php
class Locator {
protected $_obj = array();
protected $_file_extension;
function __construct($ext='.php') {
$this->_file_extension = $ext;
}
function loadClass($class='', $dir='') {
if (class_exists($class)) {
return true;
} else {
$file = str_replace(array('_','-'), array('/','_'), $class);
$class = str_replace('-', '_', $class);
if ($dir) {
$dir = rtrim($dir, '/') . '/';
}
$path = $dir . $file . $this->_file_extension;
if (file_exists($path)) {
include($path);
}
return class_exists($class);
}
}
function get($name, $class='', $dir='') {
if (isset($this->_obj[$name])) {
return $this->_obj[$name]; // return registered object
} else {
$obj = null;
$param = null;
if ($class) {
if (func_num_args() > 3) {
$param = array_slice(func_get_args(), 3); // get params after name/clas/dir
// if only one param then pass the param rather than an array of params
if (count($param) == 1) {
$param = $param[0];
}
}
}
if ($class) {
if (! class_exists($class)) {
$this->loadClass($class, $dir);
}
}
if (class_exists($class)) {
$obj = new $class($param);
}
if ($name) {
$this->_obj[$name] = $obj;
}
}
return $obj;
}
function set($name, $value) {
$this->_obj[$name] = $value;
}
}
// usage
$locator = new Locator();
// will load, instantiate and add to registry the 1st time -- fetch from registry thereafter
$db = $locator->get('DB', 'My_Db_Postgres', '', $config->get('db_connection_info'));
Posted: Fri Jul 06, 2007 6:46 pm
by kyberfabrikken
arborint wrote:Here's one that combines a loader and registry. I find it handy to inject those to capabilities together.
Why wouldn't you use autoload?
Posted: Fri Jul 06, 2007 6:53 pm
by Christopher
kyberfabrikken wrote:Why wouldn't you use autoload?
You could, but you don't get the control to, for example, load Models and Views from specific places -- like app, module or controller directories.