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.