We are now at the second video of the section adapter design pattern in the previous video.
We looked at composite design patterns in this video.
We will use an incompatible interface with an adapter object and unit test our printer adapter.
We will also see the implementation of the adapter design pattern.
One of the most commonly used structural patterns is the adapter pattern.
Like in real life where you have to plug adapters and bolt adapters in go an adapter will allow us to
use something that wasn't built for a specific task at the beginning.
The adapter pattern is very useful when for example an interface gets outdated and it's not possible
to replace it easily or fast.
Instead you create a new interface to deal with the current needs of your application which under the
hood uses implementations of the old interface adapter also helps us to maintain the open or closed
principle in our apps making the more predictable too.
They also allow us to write code which uses some base that we can't modify adapt or design pattern will
help you fit the needs of two parts of the code that are incompatible at first.
This is the key to being kept in mind when deciding if the adapter pattern is a good design for your
problem.
Two interfaces that are incompatible but which must work together are good candidates for an adapter
pattern but they could also use the facade pattern for example for our example.
We will have an old printer interface and a new one.
Users of the new interface don't expect the signature that the old one has and we need an adapter so
that the users can still use an old implementation if necessary.
Here are the requirements and acceptance criteria.
Having an old interface called Legacy printer and a new one called Modern printer create a structure
that implements the modern printer interface and can use the legacy printer interface as described in
these steps.
First we create an adapter object that implements the modern printer interface.
Next the new adapter object must contain an instance of the legacy printer interface.
And lastly when using modern printer it must call the legacy printer interface under the hood pre fixing
it with the text adapter.
Now we move on to unit testing our printer adapter lets open the adapter dot go file.
Here we have written the legacy code but we weren't tested as we should imagine that it isn't.
Our code the legacy interface called Legacy printer as a print method that accepts a string and returns
a message.
Our my legacy printer struct implements the legacy printer interface and modifies the past string by
prefixes the text legacy printer.
After modifying the text the my legacy printer struct prints the text on the console and then returns
it.
Next we declare the new interface that will have to adapt.
So this is the new printer interface.
In this case the new print stored method doesn't accept any string as an argument because it will have
to be stored in the implementers in advance.
We call our adapter patterns printer adapter interface.
As mentioned earlier the printer adapter must have a field to store the string to print.
It must also have a field to store an instance of the legacy printer adapter so let's save this file
and move to the adapter test.
Dot go file where we have written the unit tests.
Now we use the message Hello world for our adapter when using this message with an instance of the my
legacy printer struct it prints the text legacy printer hello world we created an instance of the printer
adapter interface called adapter we passed an instance of the my legacy printer struct as the legacy
printer field called old printer.
Also we set the message we want to print in the message field then we use the print stored method of
the modern printer interface.
This method doesn't accept any argument and must return the modified string.
We know that the my legacy printer struct returns the past string prefixed with the text legacy printer
and the adapter will prefix it with the text adapter so in the end we must have the text legacy printer
colon adapter hello world as we are storing an instance of an interface we must also check that we handle
the situation where the pointer is nil.
This is done with the test which you see highlighted here.
If we don't pass an instance of the legacy printer interface the adapter must ignore its adapt nature
and simply print and return the original message.
Time to run our tests so move on to the terminal and run the command go test hyphen V.
Here's the output and you can see that our test has failed.
Now let's step further to see the implementation to make our single test pass.
We must reuse the old my legacy printer that is stored in printer adapter struct.
Now we need to make some changes to our code.
So let me add the lines of code here.
Okay in the print stored method we check whether we actually have an instance of the legacy printer
in this case.
We compose a new string with the stored message and the adapter prefix to store it in the returning
variable called new message.
Then we use the pointer to my legacy printer struct to print the composed message using the legacy printer
interface.
In case there is no legacy printer instance stored in the old printer field we simply assign the stored
message to the returning variable new message and return the method.
This should be enough to pass our tests so let's save the file and navigate to the terminal to run the
test again execute the command.
Go test hyphen v perfect.
Now he can still use the old legacy printer interface by using this adapter while we use the modern
printer interface for future implementations.
Just keep in mind that the adapter pattern must ideally just provide the way to use the old legacy printer
and nothing else.
This way its scope will be more encapsulated and more maintainable in the future.
In this video with the adapter design pattern you've learned a quick way to achieve the open or close
principle in your applications instead of modifying your old source code you have created a way to use
the old functionality with a new signature in the next video.
We will learn about the bridge design pattern.