A design pattern in the top trending for programmers. Adapter is a design pattern born to meet a need, a certain feature that we do not know in advance. Let’s find out together.
I. Adapter – Structural Pattern
In the most common cases, when our interface starts to make adjustments to meet a new requirement – for example, but too difficult to modify as well as taking a lot of time. Now the Adapter Pattern will come in handy. Simply put, it’s the same interface with the same properties, but born to meet this new need, instead of having to modify everything on the old interface.
II. What do adapters bring to developers?
The Adapter design pattern helps us not to violate the second principle of the SOLID principle when encountering a problem of the same nature, but with different implementations that force us to separate into many separate interfaces but operate almost similarly.
III. Practical examples
For a specific example, we need to implement a module that can execute Http requests, including FetchModule and AxiosModule. Users who use FetchModule will not care what AxiosModule will do, but in case you need to use axios, users can still use it through AixosModule. At this point, applying the Adapter pattern will be effective. At a glance, we have the work to do:
- Create an adapter object containing the FetchModule instance
- Create an adapter object that contains an AxiosModule instance
- When using the above modules to execute http requests via ClientModule, we are passing the form of the adapter object
IV. Implementation
For simplicity, I just implemented the Http module with only Get method. First create the Http . package
1 2 3 4 5 6 7 | <span class="token keyword">package</span> adapter <span class="token keyword">type</span> Http <span class="token keyword">interface</span> <span class="token punctuation">{</span> <span class="token function">Get</span> <span class="token punctuation">(</span> url <span class="token builtin">string</span> <span class="token punctuation">)</span> <span class="token punctuation">(</span> <span class="token keyword">interface</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token builtin">error</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
Next, we create 2 modules Fetch and Axios. Both have the Get . method
1 2 3 4 5 6 7 8 9 10 11 12 | <span class="token keyword">package</span> adapter <span class="token keyword">import</span> <span class="token string">"fmt"</span> <span class="token keyword">type</span> Fetch <span class="token keyword">struct</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token punctuation">(</span> m <span class="token operator">*</span> Fetch <span class="token punctuation">)</span> <span class="token function">Get</span> <span class="token punctuation">(</span> url <span class="token builtin">string</span> <span class="token punctuation">)</span> <span class="token punctuation">(</span> <span class="token keyword">interface</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token builtin">error</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> fmt <span class="token punctuation">.</span> <span class="token function">Printf</span> <span class="token punctuation">(</span> <span class="token string">"Http Get with Fetch: %sn"</span> <span class="token punctuation">,</span> url <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">nil</span> <span class="token punctuation">,</span> <span class="token boolean">nil</span> <span class="token punctuation">}</span> |
1 2 3 4 5 6 7 8 9 10 11 12 | <span class="token keyword">package</span> adapter <span class="token keyword">import</span> <span class="token string">"fmt"</span> <span class="token keyword">type</span> Axios <span class="token keyword">struct</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token punctuation">(</span> m <span class="token operator">*</span> Axios <span class="token punctuation">)</span> <span class="token function">Get</span> <span class="token punctuation">(</span> url <span class="token builtin">string</span> <span class="token punctuation">)</span> <span class="token punctuation">(</span> <span class="token keyword">interface</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token builtin">error</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> fmt <span class="token punctuation">.</span> <span class="token function">Printf</span> <span class="token punctuation">(</span> <span class="token string">"Http Get with Axios: %sn"</span> <span class="token punctuation">,</span> url <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">nil</span> <span class="token punctuation">,</span> <span class="token boolean">nil</span> <span class="token punctuation">}</span> |
Client module is simply a module we use to perform an http request, including the following:
1 2 3 4 5 6 7 8 9 | <span class="token keyword">package</span> adapter <span class="token keyword">type</span> Client struc <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token punctuation">(</span> c <span class="token operator">*</span> Client <span class="token punctuation">)</span> <span class="token function">Get</span> <span class="token punctuation">(</span> http Http <span class="token punctuation">,</span> url <span class="token builtin">string</span> <span class="token punctuation">)</span> <span class="token punctuation">(</span> <span class="token keyword">interface</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token builtin">error</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> http <span class="token punctuation">.</span> <span class="token function">Get</span> <span class="token punctuation">(</span> url <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
The Get method in the Client module takes as an argument the instance you want to use (Fetch or Axios) along with the url. As mentioned in part 3, we do not call directly to the specific module Axios or Fetch, but through the adapter for it.
Let’s implement the adapter for them as follows
1 2 3 4 5 6 7 8 9 10 | <span class="token keyword">package</span> adapter <span class="token keyword">type</span> FetchAdapter <span class="token keyword">struct</span> <span class="token punctuation">{</span> Instance <span class="token operator">*</span> Fetch <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token punctuation">(</span> m <span class="token operator">*</span> FetchAdapter <span class="token punctuation">)</span> <span class="token function">Get</span> <span class="token punctuation">(</span> url <span class="token builtin">string</span> <span class="token punctuation">)</span> <span class="token punctuation">(</span> <span class="token keyword">interface</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token builtin">error</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> m <span class="token punctuation">.</span> Instance <span class="token punctuation">.</span> <span class="token function">Get</span> <span class="token punctuation">(</span> url <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
1 2 3 4 5 6 7 8 9 10 11 | <span class="token keyword">package</span> adapter <span class="token keyword">type</span> AxiosAdapter <span class="token keyword">struct</span> <span class="token punctuation">{</span> Instance <span class="token operator">*</span> Axios <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token punctuation">(</span> m <span class="token operator">*</span> AxiosAdapter <span class="token punctuation">)</span> <span class="token function">Get</span> <span class="token punctuation">(</span> url <span class="token builtin">string</span> <span class="token punctuation">)</span> <span class="token punctuation">(</span> <span class="token keyword">interface</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token builtin">error</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> m <span class="token punctuation">.</span> Instance <span class="token punctuation">.</span> <span class="token function">Get</span> <span class="token punctuation">(</span> url <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
So that’s the implementation part, next let’s run the executable code and see the results below
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <span class="token comment">/* Example Adapter */</span> fmt <span class="token punctuation">.</span> <span class="token function">Println</span> <span class="token punctuation">(</span> <span class="token string">"*** Example Adapter ***"</span> <span class="token punctuation">)</span> client <span class="token operator">:=</span> <span class="token operator">&</span> adapter <span class="token punctuation">.</span> Client <span class="token punctuation">{</span> <span class="token punctuation">}</span> fetchAdapter <span class="token operator">:=</span> <span class="token operator">&</span> adapter <span class="token punctuation">.</span> FetchAdapter <span class="token punctuation">{</span> Instance <span class="token punctuation">:</span> <span class="token operator">&</span> adapter <span class="token punctuation">.</span> Fetch <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> client <span class="token punctuation">.</span> <span class="token function">Get</span> <span class="token punctuation">(</span> fetchAdapter <span class="token punctuation">,</span> <span class="token string">"https://www.google.com"</span> <span class="token punctuation">)</span> axiosAdapter <span class="token operator">:=</span> <span class="token operator">&</span> adapter <span class="token punctuation">.</span> AxiosAdapter <span class="token punctuation">{</span> Instance <span class="token punctuation">:</span> <span class="token operator">&</span> adapter <span class="token punctuation">.</span> Axios <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token punctuation">}</span> client <span class="token punctuation">.</span> <span class="token function">Get</span> <span class="token punctuation">(</span> axiosAdapter <span class="token punctuation">,</span> <span class="token string">"https://www.bornhup.com"</span> <span class="token punctuation">)</span> fmt <span class="token punctuation">.</span> <span class="token function">Print</span> <span class="token punctuation">(</span> <span class="token string">"*** End of Adapter ***nnn"</span> <span class="token punctuation">)</span> |
Result:
With the Adapter design pattern, we have complete flexibility in that the Client can actively use the http module it wants. The implementation for each module is also separated, there is no difficulty when modifying this module but affecting other modules, as well as easily adding modules if any, what you need is to add implementations and adapters just give it
V. Conclusion
With the adapter design pattern, we get the clearest illustration of the Open/Close nature of the SOLID principle applied to our own products. Instead of having to modify it with difficulty to adapt to new requirements, we simply implement it.
Thank you for viewing the article.