Dynamic forms based on VO/DTO & Type-map
Posted: Wed Jan 10, 2007 11:29 am
I'm currently in the process of redesigning a PHP5 framework which so far has been mimicking things like CakePHP or Symfony (not using Active Record!)
So far we've been using the DAO-pattern and simply passed our VO/DTO-objects directly from the controller to the view.
This lead to extremely fast development since we could do things like:
In the controller:
Int the view:
Problems arise though, when the VO/DTO-objects change and the views subsequently has to be updated.
Obviously the views are too dependent on the VO's methods... so what to do?
"A generic model which could be iterated in the view", you say?
But what about the forms?.. We'll.. We probably all know how boring it can be to design forms.
So how about this approach?:
VO/DTO:
Type-map (maps matching getters/setters in the VO/DTO):
Converts a customer to a list-object (using "get_class_methods()" in the DynamicListAdapter-class):
Imaginary form-generator call:
Resulting in a Form-object with a TextField and HiddenField as its children, which could be outputted like:
This way the view (with the formgenerator-call) is only coupled with the type-map.
So when the VO/DTO changes, you would only have to update the Type-map.
Thoughts, critics (and "HERESY!"-claims) appreciated, and sorry for the long post.
So far we've been using the DAO-pattern and simply passed our VO/DTO-objects directly from the controller to the view.
This lead to extremely fast development since we could do things like:
In the controller:
Code: Select all
$this->posts = $postDAO->findAll();Code: Select all
foreach($posts as $post)
{
$this->add(new Headline($post->getTitle));
}Obviously the views are too dependent on the VO's methods... so what to do?
"A generic model which could be iterated in the view", you say?
But what about the forms?.. We'll.. We probably all know how boring it can be to design forms.
So how about this approach?:
VO/DTO:
Code: Select all
class Customer
{
private $id;
private $name;
public function setId($id)
{
$this->id = $id;
}
public function getId()
{
return $this->id;
}
public function setName($name)
{
$this->name = $name;
}
public function getName()
{
return $this->name;
}
}Code: Select all
class CustomerControlMap extends BaseControlMap
{
private $maps;
public function __construct()
{
$this->maps = array();
$this->maps['name'] = new TextField();
$this->maps['id'] = new HiddenField();
}
public function getMap($fieldName)
{
return $this->maps[$fieldName];
}
}Code: Select all
class CustomerList extends DynamicListAdapter
{
public function __construct(Customer $customer)
{
parent::__construct($customer);
}
public function getList()
{
return parent::getList();
}
}Code: Select all
$list = new CustomerList(new Customer());
$form = FormGenerator::generate($list->getList(), new CustomerControlMap());
$form->setAction('action.php');
$form->setMethod('post');Code: Select all
<form method="post" action="action.php">
<input type="hidden" name="id" />
...
</form>So when the VO/DTO changes, you would only have to update the Type-map.
Thoughts, critics (and "HERESY!"-claims) appreciated, and sorry for the long post.