Question

How do people design their service layer interfaces?

I'm programming a large web application (in PHP) and we're using MVC, and programming thin controllers e.g. (pseudo code follows)

public savePersonAction() {
    $input = filter($_GET);
    ... input validation ...

    $result = $this->_service->savePerson( ? );

    ... etc
}

Should savePerson in the service take an argument of the entire $input structure or context (in PHP, an associative array)?

E.g. this -

public function savePerson(array $input) {

or should one separate out all the input fields and provide a "hard" interface e.g.

public function savePerson($title, $firstName, $lastName, $dateOfBirth, ... etc.. for many more) {

Thanks.

Paul

Was it helpful?

Solution

If you're going to follow the MVC spirit your savePerson method should not accept the raw input. It shouldn't be directly coupled with the format of the data coming from the ui. Instead it should accept input defined in the terms of your service domain, like a "person" object. (This could just be an associative array like Cobby suggested). It would be the job of the controller's action method to map the raw input to the format required by the service.

The benefit of this extra translation step is that it isolates your service (model) from the ui. If you implement a different ui, you don't need to change the service interface. You just need to write new controllers (and views, of course).

While your example like savePerson($title, $firstName, $lastName...) is the right idea, it's usually a bad sign when you have methods with more than 2 or 3 arguments. You should be able to group related arguments into some kind of higher-level object.

OTHER TIPS

My MVC applications are structured like this: Controller -> Service -> ORM/other library

To answer your question, typically in your controller you will be getting form data as an array, i.e. $form->getValues() or something similar. In terms of maintainability it's best if your Services except arrays as arguments, that way if you add another field to a form, you only have to update the form and the service, your controller can remain untouched and still work.

So I think go with your first example:

public function savePerson($personArray);

Furthermore, you shouldn't need a "hard" interface because your form library will take care of validation/filteration/sanitization so we can assume that the associative array will be valid, plus the method definition will get ridiculously long with named parameters.

I would separate out all the input fields and provide a "hard" interface in Service e.g.

public function savePerson($title, $firstName, $lastName, $dateOfBirth) {...}

Its cleaner and there are no assumptions needed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top