Wednesday, November 2, 2011

Request, Response, Request, Response

In a layered application (not tiered) we usually have an UI layer, a business layer, communication layer and DB layer (the most common applications are distributed this way, it seems natural). This obviously leads to calls between layers, for example, the user clicks in the UI to get a report of the clients, the UI asks a "service" in the business layer to get that report, and probably the business layer ends up calling another "service" from DB or Communication layer.

So far so good, but what I want to talk about today is how this is implemented. I really don't know why, but I usually see a lot of Requests and Responses classes going through layers. Meaning that each service receives a request and returns a response, so each client layer needs to create that request and process that particular response. In our example it would be something like this:

In the UI:


This is the usage of the Service, as I commonly see it in legacy codes. But what about the interfaces of these classes?, well they usually tend to be something like:


And the "Service" usually looks like:

So if we want to get a report of  Clients by year and city we call the first constructor of the ClientRequest class and then the first method of the ClientBusinessService. If we want Clients by Country, we only set the country in the request and call the second method of the service.

Which are the things I don't like?

  1. Request and Responses are Data classes.
  2. Requests and responses end up having lots of attributes that are not needed
  3. Requests end up having service configuration attributes
  4. Interfaces are not representatives of the functionality. We loose readability
  5. We always need translators
  6. Code overhead


1. Requests and Responses are data classes.

Data classes are not good, a class is represented by its attributes and methods, so if a class only have attributes then it is probably not needed. On the other hand, Data classes promote feature Envies from other classes that need the information that they contain, leading to maintenance headaches!. Another thing to consider is that the request will probably have setters, which will make your life a complete nightmare.

2. Requests and responses end up having lots of attributes that are not needed

The country is an example of this point. Of course my example is quite simple, but take under consideration the in real world the services are more complex but for my simple example some questions come into my mind:

shall I write one constructor per service method? Obviously the request depends on the Service call, we need to make sure that we call the constructor needed when we call the service. This is not ideal.

shall I write only one constructor for the request and pass null if the attribute is not needed?. This is horrible, we should never pass null to a constructor, this leads to a lot of problems (one is the continuous null checking in all the services that use that request)

shall I leave the default constructor and set the attributes  I need?. You still have the problem of nulls and setters are always a nightmare, I would recommend no to add setters in your class (as a general rule), they are the seed of side effects.

 for the year and city request, do I need the country or not?. This is the main key that I haven't discussed. YOU NEED TO KNOW WHICH ATTRIBUTES ARE NEEDED FOR THAT CALL, the interface does not define that clearly, you need to know how the service is implemented in order to create the request!, by calling getClientsByYearAndCity you don't know if the country is not needed, that's only your assumption.

3. Requests end up having service configuration attributes

Maybe this is not entirely related to Requests and Responses, but something I find associated to this pattern is that the request does not only have domain specific information. As it is easy to add new members into the Request class, people start adding things that are needed to configure the Service, for example, connection Ports, URL, session information. This is horrible because the service might vary the implementation (you can have to classes that implement the service interface, let's say one goes through a web  service to get that information, and another goes through the database), you probably don't need some information for both implementations. The Service interface must reflect the Service responsibility, not its implementation.

4. Interfaces are not representatives of the functionality. We loose readability

This is related with what I already said, you don't know for sure the parameters that you need to send to the Service in order to make it work. It is not clear what a request represents, it is not clear by reading the interface which is the expected result. I've been nice and wrote some clear methods but you may not find that in real world.

5. We always need translators

Instead of returning domain objects we return Responses, but responses are plain objects that does not have any function, so or you need an utility class (hate that names) that reads the response and provides you with the information you need completely processed, or you read the response and create a new object with that information.

6. Code overhead

You need a lot of lines, for translating the request and the response,  for null checking, constructors, request and response classes. This makes the code unnecessary complex.


These are the reasons I can think right now,  probably I'll find more, but I'll leave them for another post :-)