Application description
I have an application of the following structure, simplified:
Http request ↓ +-----------------+ | RequestParser | +-----------------+ ↓ Business layer request object
Problem code
The request parser layer accepts the input parameters, validates them and builds the business-layer request object. The code looks like that:
public function processMyRequest()
{
validationForm =
Form::create()
.addIntegerValidator('order_id')
.addStringValidator('external_id')
;
if (validationForm.hasErrors()) {
throw new Exception();
}
return
BusinessRulessObject::create()
.setOrderId(validationForm.getParameter('order_id'))
.setExternalId(validationForm.getParameter('external_id'))
;
}
Some prerequisites
The form can be huge, so does the business layer object. Unfortunately, the Form class belongs to framework and it is final, so I can not inherit the concrete form from the base one where I could specify all the validators. The agreed solutions was to create this forms via Factory classes (this is not the Factory template though as it is not needed here: no mocks in tests, no polymorphism in client code). The RequestParser class can handle several requests.
Better version
So now the code looks like this:
public function processMyRequest()
{
validationForm = FormFactory.createSomeForm();
if (validationForm.hasErrors()) {
throw new Exception();
}
return
BusinessRulessObject::create()
.setOrderId(validationForm.getParameter('order_id'))
.setExternalId(validationForm.getParameter('external_id'))
;
}
How can I make it better? Version 1
But how should I create my object? Should I have some factory that creates it from form? I.e.,
public function processMyRequest()
{
...
return BusinessRulessObjectFactory::createMyConcreteObject(form);
}
Version 2
Or should BusinessRulessObject class have some method like createFromForm()
, i.e.
public function processMyRequest()
{
...
return BusinessRulessObject::createMyConcreteObject(form);
}
Version 3
Or RequestParser's method createFromForm()
would be enough, i.e.
public function processMyRequest()
{
...
return createMyConcreteObject(form);
}
private function createMyConcreteObject(Form validationForm)
{
return
BusinessRulessObject::create()
.setOrderId(validationForm.getParameter('order_id'))
.setExternalId(validationForm.getParameter('external_id'))
;
}
So?...
I guess I should choose between the first and the second option, but what aspects should I take into consideration when choosing the way object should be created? And, actually, what way is preferable in my case?