From the course: Java Design Patterns: Structural

Implement the Adapter pattern - Java Tutorial

From the course: Java Design Patterns: Structural

Start my 1-month free trial

Implement the Adapter pattern

- [Instructor] In this example, I've got an app that calculates the prices of different kinds of vehicles. I'm going to refactor this app to use the adapter pattern. But before I do, I'm just going to explain how this app works at the moment. So first of all, this app has an interface called PriceCalculator. And this has a single method called calculatePrice, and that returns a string. So there are two concrete implementations of this interface. One of them is called CarPriceCalculator, and the other is TruckPriceCalculator. So both these classes implement PriceCalculator, as they override the calculatePrice method. In a real life app, this would have a more complicated and realistic formula to work out the price. But just to keep things simple, I've made up a random simple formula to come up with a price. Finally, there is a main class. The main class has a method called printVehiclePrice, and this takes a PriceCalculator as an argument. It then uses the calculatePrice method on the calculator to calculate the price. And then it just prints out a message to the console saying, the price of this vehicle is, and then the price. In the main method itself, I'm first of all creating a CarPriceCalculator object, so I'm doing new CarPriceCalculator. And in this case, I need to pass in the model, so I've put a Ford, and then the age, and I've put three years. And then I'm calling printVehiclePrice, and passing in the CarPriceCalculator. So this will print out the price of the car to the console. Below that I'm doing the same with a TruckPriceCalculator. So I'm creating a new TruckPriceCalculator, and for trucks I need to pass in the age and the mileage, so I've just put 10 and zero. Then I'm calling the printVehiclePrice method again, and passing in the TruckPriceCalculator. So if I run this app, I can see in the console that it prints out the price of the two vehicles. So the first is 2700 USD, and the second is 9000 USD. So this app tells me the prices of vehicles in US dollars. But in other countries, the prices might be calculated differently, and I don't have any implementations for these. However, I do have a dependency on a third party app, called UK Car Price Calculator, which can be used to return the price of a car in British pounds using a different algorithm. So if I look inside my lib folder, I can see that I have a jar file called uk-car-price-calculator. I also have the Java docs for this third party app. So I'm going to look at those. I can see in the Java docs that this app has a class called UKCarPriceCalculator. So if I click on that, I can see that this has a constructor, which takes two arguments, a model and the age of the car. And there's also a method called getPrice, which returns an integer, which is the price of the car. So if I go back to my app, because I have a dependency on UK Car Price Calculator, I can create a UKCarPriceCalculator object. So I'll do, UKCarPriceCalculator and I'll call it ukCarPriceCalculator is equal to new UKCarPriceCalculator. And now I need to pass in the model, so I'll just pass in BMW and the age, so I'll say seven. But I can't now call the print vehicle price method and pass in my UKCarPriceCalculator because printVehiclePrice is expecting a price calculator object. And this UKCarPriceCalculator knows nothing about the price calculator interface. So to make this work, I need to create an adapter. So I'll create a new class in my IDE by right clicking on the Java folder and going to New, Java Class. And I'll call this class Adapter. So the first thing I need to do is make sure that this class implements the PriceCalculator interface. Next, I'm going to create a field of type UKCarPriceCalculator, which I'll call ukCarPriceCalculator. Next, I'll create a constructor, so I'll do public Adapter, and I'm going to pass in a ukCarPriceCalculator object. And then inside the constructor, I'm going to do this.ukCarPriceCalculator is equal to the ukCarPriceCalculator that I'm passing in the constructor. Finally, I need to override the calculatePrice method of the PriceCalculator interface. So I'll do public string, calculatePrice and I'll do return. So I need to return a price. And I know from the Java docs that the UKCarPriceCalculator class has a method called getPrice, so I can do UKCarPriceCalculator.getPrice, and then I'll add onto the string GBP, so that I know it's returning British pounds rather than US dollars. Now all I need to do is go back to my Main class. And in my main method, below where I've created my UKCarPriceCalculator, I can create an Adapter object, which I'll call adapter. So I'll do is equal to new Adapter, and I'll pass in my ukCarPriceCalculator. Next, I can now call the printVehiclePrice method, and I can pass in the adapter object. So now if I rerun this, I get the price of a third vehicle, which is 5475 GBP. So this is how the adapter pattern can enable you to use classes in your application that you wouldn't otherwise be able to because they don't fit with your class hierarchy.

Contents