@pgb101 - thank you for your very thoughtful response
My intention with the following response is to walk through some different possibilities without being pedagogical in the slightest.
To me the biggest culprit in all of this is the framework. In an ideal world
I would expect Zend to populate the form (via introspection) and make that
available via a method param. That would make the following possible:
public function emailPreferencesAction(Zend_Form emailPreferencesForm) {
$emailPreferencesVO = new EmailPreferencesValueObject(emailPreferencesForm);
$submittedEmailPreference = new Account_Models_EmailPreference($emailPreferencesVO);
}
Appears relatively smell free to me. No bucket programming, well defined interfaces, allows for type hinting etc. The only issue, that I can see, is having to update both the VO and the model if there is a change to the (hypothetical) form.
Back to the real world. The issue is the associative array we are forced to deal with. That leads to the following code possibilities:
// Code possibility #1
//
public function emailPreferencesAction() {
$submittedEmailPreference = new Account_Models_EmailPreference();
$submittedEmailPreference->setValue1($this->getRequest->getParam('value1'));
......
......
$submittedEmailPreference->setValueN($this->getRequest->getParam('valueN'));
}
Stinks to high heaven? Sure. We’re not encapsulation that which varies. Leads to code duplication (having to
repeat this whenever we create an instance of EmailPreference). Also, what if we forget to call one (or more)
of the mutators? I don’t think anyone is advocating this, correct?
Next up:
// Code possibility #2
//
public function emailPreferencesAction() {
$submittedEmailPreference = Account_Models_EmailPreference::create($value1, $value2.....$valueN);
//OR
$submittedEmailPreference = new Account_Models_EmailPreference($value1, $value2.....$valueN);
....
}
Works fine for 3/4 params. Anymore than that and we start a merry walk down this path - TooManyParams
Interesting - mentioned as a possible solution is to pass in an associative array, which leads me to:
// Code possibility #3
//
public function emailPreferencesAction() {
$submittedEmailPreference = new Account_Models_EmailPreference($params);
....
}
Reservations regarding this possibility have been expressed earlier (bucket programming etc). However there isn’t
a general consensus as some folks advocate this possibility and see it as reasonably (if not entirely) smell free. Finally:
// Code possibility #4
//
public function emailPreferencesAction() {
$emailPreferencesVO = new EmailPreferencesValueObject($params);
$submittedEmailPreference = new Account_Models_EmailPreference($emailPreferencesVO);
....
}
We’re still indulging in bucket programming but the model interface is well defined. Of course if we add a new field to our UI, we’d have to update both the value object and the model as mentioned earlier.
Unless I’m missing a key point it seems to me that given the framework, a code smell is unavoidable (unless of course you don’t think #3 is an issue. I’m trying my hardest to be inclusive here!) But to those who feel #3 is an issue, is it really a matter of choosing the least smelly code? If it is personally I’d go for #4.
Thoughts?
Cheers,
-Sam