Adapter jako wzorzec pozwala na połączenie niekompatybilnych interfejsów. Typowym scenariuszem jest sytuacja, gdy np nowe komponenty muszą być zintegrowane z aktualnymi, przez co trzeba napisać adapter, który umożliwia im komunikację.
Typowym przykładem jest np użycie nowej biblioteki w systemie, która np wymaga nowego formatu danych do rysowania wykresów na podstawie JSON. Nasz system używa jeszcze formatu xml, dlatego musimy użyć adapteru, który połączy oba interfejsy przepisując jeden format danych na drugi.
Adapter może kojarzyć się z fasadą, ale w jej przypadku tworzymy interfejs od zera, natomiast w adapterze istnieją już interfejsy, które musimy skomunikować.
Poniższy przykład pokazuje adapter dla nowo wprowadzonego interfejsu transportu z lepszymi cenami. Aplikacja nie jest z nim kompatybilna, dlatego użyty jest adapter, który w wywołaniu wygląda jak poprzedni interfejs, ale korzysta z nowego rozwiązania.
// stary interfejs
function Transport(credentials) {
this.send = function(addr, weight) {
// obliczenie kosztu
return 120;
}
}
// poprzednie api
let addr = {country: "UK"};
let credentials = {token: "user:zaq123"};
let oldTransport = new Transport(credentials);
let oldPrice = oldTransport.send(addr, 5);
Poniżej nowy interfejs oraz adapter, który zachowuje się dla aplikacji jak poprzedni interfejs:
function NewTransport() {
return {
login: function(credentials){},
setPriority: function(priority){},
setDestination: function(addr){},
getPrice: function(weight){
return 110; }
}
}
Następnie adapter:
// adapter
function TransportAdapter(credentials) {
let shipping = new NewTransport();
shipping.login(credentials);
return {
send: function(addr,weight){
shipping.setPriority("normal");
shipping.setDestination(addr);
return shipping.getPrice(weight);
}
};
}
Łączymy wszystko razem:
// nowe api poprzez adapter
let newTransport = TransportAdapter(credentials);
let newPrice = newTransport.send(addr,5)
console.log(newPrice); // 110