Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Js design 1
  • Overview
  • Transcript

4.3 The Adapter Pattern

We all know that a public API should never change once it's been released. But that doesn't mean it doesn't ever happen. With the Adapter pattern, we can make as many changes to our API internally as we wish, and have the public interface adapted to the internal API.

4.3 The Adapter Pattern

Hi, folks. In this lesson, we're going to look at, The Adapter Pattern, in JavaScript. The adapter pattern is used to convert one interface into another. In JavaScript, an interface is the methods and properties exposed by an object, the things that we use to interact with it. The adapter pattern is useful when something changes and we don't want to have to go through our entire code base in order to update how the rest of the code uses the thing that is changed. An adapter isn't always suitable. And if the thing being changed isn't widely used throughout your application, it may be just as easy to refactor any code that does use it, as it would be to create the adapter in the first place. So let's take a look at the basic pattern. We can create a new folder for this example and call it adapter. And inside this, we'll need a new script file, which we can call oldInterface. Let's just give it a basic constructor. And maybe we can add a method to its prototype. And let's just add a simple console log to this method. And let's just have this module return a new instance of itself. Great. Okay, so super basic, but that's fine for now. Let's add the init module now, just so that we can use our OldInterface, And let's just invoke the doSomethingOld method of the oldInterface. And let's load the new init module in our main file. And let's try running the example in our browser just to verify that the oldInterface is being used. Okay, so it's definitely doing the old thing. So in this example, we're just using our old module in one place, but in reality, we could be using this guy all over our code base. It might even be a module provided by a third party, or a vendor, or something that we can't or don't want to update directly. So instead, let's create a newInterface. So again, the newInterface will be very, very simple. Let's just have a basic constructor. And let's add a new method to its prototype. And we can even have this method accept a new argument. And again, we'll just keep it to a simple console log. And again, we can return a new instance of the NewInterface. It's pretty similar to the old module, in this example, but the name of the method it exposes is different, and this time the method takes an argument. So now this new version is available. We could go through our entire app and refactor everything to use the NewInterface. Or, if that's a pretty big task, we can create an adapter instead, so that we only have to make minimal changes to our existing code. The adapter is almost the only new code that we need to write. So let's create a new file now called adapter. And in fact, we'll call it oldInterfaceadapter. So we need to use the require function this time. And let's load up the newInterface, first of all. So now the adapter can return an object that exposes a method that has the same name as the method on the oldInterface, but it's actually going to use the newInterface. This module has a dependency on the newInterface, as it will need to wrap its' new methods in the oldInterface. We can then return an object that exposes the old method name to the outside world, while invoking the new method internally. The old method didn't take the argument expected by the new method, and so the existing code doesn't pass it. To make the fewest changes possible, we can calculate, define, or otherwise obtain the value of this new argument in the adapter. In this case, we just use a hard coded string. So now to use the new interface as seamlessly as possible, we just need to update our main file to load the adapter instead of the old module. So let's just go back to the browser now. And it looks like there's a typo in my method name, let's just fix that quickly. And that's in the adapter, the oldInterface adapter. Let's try that again. So as you can see, we're doing the new thing. But all we've done is add an adapter and change the name of the module that is being loaded. Now, we could just leave it at that. But let's just go back to the code quickly. It's not super intuitive for somebody else coming to update this file, if they don't notice that the module being loaded is the adapter, rather than the oldInterface. Now the fact that the module name has got the word adapter in its' name, should be a big clue that we're using the adapter pattern here. But just because we think that it should be pretty obvious, that doesn't mean that it's going to be pretty obvious to everybody. So what we should do is just make sure that it's clear which interface we're using. So let's just update the name of the variable that contains the interface. So now it's a bit more clear that we're using an adapter. Because we're using require.js, we could also not have to update anything at all and just use the require config to map the new adapter to the old module, so that when another module tries to load the old module, require gives it the adapter instead. But this is even less transparent than not renaming a module in the code as we just have done, so it should probably be avoided in most cases. As a side note, the adapter pass in is a great example of when to apply pass ins. An adapter wouldn't usually be part of the up front design of an application. Originally, the app would be using the oldInterface. The need for the adapter would arise later, most likely as a result of another module or dependency changing. Generally, the need and opportunities to use patterns, arise over time as the application grows and changes. It's common to refactor to patterns rather than to build them in from the start. So in this lesson, we looked at the adapter pattern and saw that it can be used to adapt one interface to another. This can allow us to change part of our application without having to make extensive changes to other parts of the code. We simply create an adapter instead. Thanks for watching.

Back to the top
Continue watching with Elements