Why adapter pattern
It just defines the brewCoffee method which you can call to make a cup of coffee. That seems to be a good approach that enables you to use different coffee machines with your application. The only requirement is that all classes that represent a coffee machine implement the FilterCoffeeMachine interface.
As you can see, the method has the same name as the one defined by the FilterCoffeeMachine interface, but the method signature is incompatible. It expects a parameter and declares an exception. I will not change the class so that it implements the required interface.
The BasicCoffeeMachine implements that interface and I would need to change that class whenever I change the interface.
By introducing an adapter class, that implements the FilterCoffeeMachine interface and wraps the PremiumCoffeeMachine class, you enable your FilterCoffeeApp to use the coffee machine.
The interface and the existing class are not too different. That makes the implementation of the adapter class relatively simple. As you can see in the code snippet, the FilterCoffeeAdapter class implements the FilterCoffeeMachine interface and expects a PremiumCoffeeMachine object as a constructor parameter. It keeps that object in a private field so that it can use it in the brewCoffee method.
The implementation of the brewCoffee method is the critical and for most adapter classes, the most difficult part. In this case, the PremiumCoffeeMachine class provides a method that you can call to perform the task. In this example, there is no perfect way to do that.
You can either write a log message and return null, as I did in the code snippet, or you can throw a RuntimeException. In your application, you might have better ways to handle the exception. You might be able to perform a retry or to trigger a different business operation. The adapter is also responsible for transforming data into appropriate forms.
You can use the Adapter design pattern when you have to deal with different interfaces with similar behavior which usually means classes with similar behavior but with different methods. They will share common behavior like open menu, start playback, connect to a network and etc but each library will have a different implementation of it with different method names and signatures.
These different vendor specific implementations are called Adaptee in the UML diagrams. So, in your code called Client in the UML diagrams , instead of hard code the method calls of each vendor or Adaptee , you could then create a generic interface called Target in UML diagrams to wrap these similar behaviors and work with only one type of object. The Adapters will then implement the Target interface delegating its method calls to the Adaptees that are passed to the Adapters via constructor.
For you to realize this in Java code, I wrote a very simple project using exactly the same example mentioned above using adapters to deal with multiple smart TV interfaces. The code is small, well documented and self explanatory so dig on it to see how a real world implementation would look like. You can execute the code by running org. Remember that the important thing here is to understand how classes and interfaces are assembled together to design the pattern.
I also created some fake Adaptees in the package com. Hope it helps! Say you have defined an interface I1 with method M1 and M2.
C1 and C2 implements this interface I1 , now for C1 while implementing M1 and M2 you have found no help from other existing classes so you need to write all logic by yourself. In this example C2 becomes Adapter class and C3 becomes adaptee. A very common example of the adapter pattern is done through the Service Provider Interface and is commonly used in a lot of the Java EE framework. The reason for it is to allow different implementations of Java EE but programmers simply code to the Java EE spec rather than something implementation specific.
As opposed to something like coding directly using WebSphere classes which lock you into using WebSphere. Or worse from my experience , Apache HTTP Client and find out later that because you coded to that implementation rather than the normal HttpUrlConnection you have to do a lot of recoding because it does not support the current version of TLS which would've been avoided if the original developer coded to a more stable API and we just need to upgrade Java runtime.
That's it! This is how the adapter pattern allows two incompatible interfaces to work together. Adaptive Code Agile coding with design patterns and SOLID principles Applying principles from this book, will help you create code that accommodates new requirements and unforeseen scenarios without significant rewrites.
The Adapter Pattern Converts the interface of a class into another interface this client expects. Like this content? Sign up to my newsletter and I'll send you updates and more! I consent to allow garywoodfine. About Latest Posts. Gary Woodfine. Technical Director at threenine. Gary is Technical Director at threenine.
This type of design pattern comes under structural pattern as this pattern combines the capability of two independent interfaces. This pattern involves a single class which is responsible to join functionalities of independent or incompatible interfaces.
A real life example could be a case of card reader which acts as an adapter between memory card and a laptop. You plugin the memory card into card reader and card reader into the laptop so that memory card can be read via laptop.
0コメント