Le design pattern Adapter permet d'utiliser de manière complètement transparentes deux (ou plus) librairies qui font la même chose mais qui n'ont pas la même API.
Open-Close principle
L'idée est de créer une API nouvelle et d'implémenter une classe pour cette API avec chacune des librairies. Ces classes sont appelées des adapteurs.
public class GoogleSMS { public void sendSMS(String message,String phoneNumber); public void sendSMSBulk(String message, List<String> phoneNumbers); } public class AmazonSMS { public void currentPhoneNumber(String phoneNumber); public void sendSMS(String message); public void spamSMS(List<String> message); }
Les deux librairies permettent d'envoyer des SMS mais n'ont pas la même API. Fonctionnellement, elles font les mêmes choses.
public interface SMSSender { public void sendSMS(String message,String phoneNumber); default public void sendSMSBulk(String message, List<String> phoneNumbers){ for(var phoneNumber : phoneNumbers){ sendSMS(message,phoneNumber); } } default public void sendSMSBulk(List<String> messages, String phoneNumbers){ for(var message : messages){ sendSMS(message,phoneNumber); } } }
En générale, la nouvelle API est différente des librairies que l'on veut utiliser.
public class GoogleSMS { public void sendSMS(String message,String phoneNumber); public void sendSMSBulk(String message, List<String> phoneNumbers); }
On veut coder une classe GoogleSMSAdapter
qui va implémenter l'interface SMSSender
en utilisant la librairie GoogleSMS
.
public class GoogleSMSAdapter implements SMSSender{ private final GoogleSMS googleSMS = new GoogleSMS(); @Override public void sendSMS(String message,String phoneNumber){ googleSMS.sendSMS(message,phoneNumber); } @Override public void sendSMSBulk(String message, List<String> phoneNumbers){ googleSMS.sendSMSBulk(String message, List<String> phoneNumbers); } }
On redéfinie sendSMSBulk
car googleSMS
propose une méthode dédiée.