I have bunch of REST style web services which support XML and JSON type responses. Now I have to modify existing web services such that they provide Protobuf type of responses.
Developer who has developed these services has created three layers. Service
layer, DAO
layer and Processing
layer.
Service layer calls one of the method of processing layer and processing layer calls DAO methods and returns either JSON or XML type response (POJO) to the service. Service layer then sends back this POJO to client.
For example, if service to add list of items
is called then that code roughly looks as shown below:
@Path("/item")
class ShoppingItemService {
// annotations
public ItemAddResponse addList(/* parameters required for this method */) {
ItemProcessor processor = new ItemProcessor();
ItemAddResponse response = processor.process(/* pass some data to processing layer */);
return Response.ok().format("XML").build(response);
}
}
Here ItemAddResponse
is already annotated with JAXB
type annotations for XML
response and other annotations for JSON
response.
I cannot reuse same ItemAddResponse
because Protobuf generates its own classes using schema files.
Processor class has all the business logic and If I want to add support for Protobuf then I have create new method in processor and copy-paste almost all the business logic, but just return object of protobuf generated class.
This approach is time consuming and there atleast 50+ similar methods where I have to do copy-paste work. I want to avoid this and would like to design some elegant solution.
I would like to know how can I add support for Protobuf with minimal amount of changes?
I am reading Head First Design patterns
book but this book is really huge and it will take lot of time to find proper design pattern.
Is there any design pattern which can be useful in this type of situations?
Thanks,
Chandrashekhar
Best Answer
NO!
An object oriented approach
ItemProcessor
"has all the business logic". Don't pollute the class, keep it strictly business logicItemProcessor
, whatever, all get the format they expect.OO Design Sketch
A
ItemProcessor
instance needs aTranslator
object to get the data to or from, or both, the desired form.ItemProcessor
maybe needs differentTranslator
s for interacting w/ the client and DAO respectively.So we need to make a
ItemProcessor
/Translator
composite at run time. creational design patterns help us do that.It may be that you end up designing a single, static,
Translator
class.Design patterns do not dictate your design. To start with a blank sheet of paper and say "I want to use the xyz design pattern" is wrong, wrong, wrong.
Fitting a pattern to your design
You still need to design things. Only you can define the various parts overall. From there, a creational pattern shows us how to decouple the creation of an object from its user. In this way we avoid the problem as quoted at the beginning of this answer.
Look at creation design patterns like
factory
,abstract factory
, andbuilder
.Which design pattern you use is generally driven by the complexity of building the given object. That there are 3 kinds of factory has to do with complexity.
You will tell the factory, etc. to build you something with "JSON - protobuffer" transformation for example. So maybe you get back a
ItemProcessor
that has a JSONprotobufTranformer object, or XMLprotobufTransformer, or ... whatever.