Design Patterns is a Fish & Learning to Design is Fishing
Disclaimer: The content of this blog are my views, observations and understanding about the topic. I do not intend to undermine anything. I am simply giving my perspective about it. This will help you to look at the topic from a different angle.
Give a man a fish, and you’ll feed him for a day. Teach a man to fish, and you’ve fed him for a lifetime.
We tend to request help from our colleagues. If they offer us help, as per this saying then we will be ideally independent. But it is up to us as well, to learn on our own and make an earnest attempt to be independent. Self Learning is the best way to gain understanding of something. I think Design Patterns might have been shared with an intent of not reinventing the same wheel and quickly using them based on our use cases. On spending enough time in the Software Industry I observed that Design Patterns are treated like a Holy Grail of effective Software Development. We should learn to design a code effectively which is AGILE enough to adapt to the changing requirement.
One fine day I was working on a code wherein I wanted to separate how different messages are structured, built, formatted, and how they are sent to other systems. I was using the usual json formatter library FasterXML – Jackson. I will explain briefly what I intended to do and how I did it without the knowledge of a Design Pattern.
Consider that you have to send messages to a system which are having different structure like shown below :
You have to restrict the Developer that they should use a pre-defined and pre-configured Object Mapper. Moreover, the basic skeleton code should be abstracted so that developer can focus only on adding new messages with different structure. A typical enterprise application fetches the data from various data sources and maps them. Assume that the data is already mapped in some other POJO and we have to extract the relevant data, as per our need. I created an abstract class which will have all the skeleton code, which looks something like this :
I wanted that map to be named before calling writeValueAsString method and wanted the implementation of the map method specific to each message mapper. I was having the knowledge of behavioural abstraction using interfaces, but our requirement needed us to ensure that order of call to map method, and writeValueAsString method is preserved.
Also, configuring the ObjectMapper instance as per our need. I chose an abstract class over interface. Moreover, the concept of abstraction using abstract class is to have some abstract entity which will have some state and behavior, which is shared across its children. Interfaces are pure behavioural abstraction, hence should be used in those cases only.
Please note below points about this class design :
- It’s abstract- which means you cannot create instances out of it
- ObjectMapper instance variable if final- which means you cannot change that to some other instance anywhere else in the code, once it’s configured in the constructor of this class
- Map method is abstract and protected ( inheritable ) so that it should be implemented by child classes only and would be accessible in the same package. It will ensure that outside code which lies beyond this package ( a modular approach) would not be able to call the method. We could not make it private, otherwise it cannot be overridden. We did not make it package private so that in future we can separate the messages in a different package
- Format method is final, and it calls the map method before calling the object mapper to convert the pojo to a JSON string. It takes the instance reference as itself ( i.e this ). The method is package private so that it should be called from the same package, ideally used by the Messenger class
That’s it! Now we can easily create messages as per the structure needed by the DestinationSystem. Below are some examples for reference, simply to explain how you can use this effectively:
I was checking some of the Behavioural Design Patterns & I stumbled upon the Template Method Design Pattern, which is a behavioral-design pattern that allows you to defines a skeleton of an algorithm in a base class. It also lets sub-classes override the steps without changing the overall algorithm’s structure. The FormattableMessage is a flavor of this pattern. In addition to behavior, it also has state for achieving the behavior. It is having a simple algorithm to map and then format. The Developer is free to map details as per the requirement.
I conclude that if we have strong fundamentals about a language and are clear about what we want to achieve with effective designing skills, then we need not rely on the Design Patterns much. Knowing a Design Pattern is good! Understanding it and various uses of the same will help you. Although, if you are totally dependent on it then you may not learn to Design a Pattern, and will have limited vocabulary of Patterns which you are aware of. One fine day you may be the one who creates anti-pattern.
Knowledge is camouflaged. All you do is explore it with your inquisitive mind.
I am an Agile Full Stack Developer, who is keenly interested in finding the answers to WHAT, HOW & WHY questions of Software Development. I believe in being Language Independent for writing a Software code. I contribute my knowledge to the developer society through blogs, and channel my artistic skills through every walks of life, including Software Development!