![Pont](/images/patterns/cards/bridge-mini.png?id=b389101d8ee8e23ffa1b534c704d0774)
Pont en Java
Le Pont est un patron de conception structurel qui scinde la logique métier ou divise de grandes classes dans des hiérarchies de classes séparées qui vont ensuite évoluer indépendamment.
Une de ces hiérarchies (souvent appelée l’abstraction) gardera une référence vers un objet de la seconde hiérarchie (l’implémentation). L’abstraction pourra déléguer certains (parfois la majorité) de ses appels aux objets de l’implémentation. Puisque toutes les implémentations ont une interface commune, elles sont interchangeables à l’intérieur de l’abstraction.
Complexité :
Popularité :
Exemples d’utilisation : Le patron de conception pont est très utile pour gérer les applications multiplateformes, prendre en charge différents types de serveurs de bases de données ou travailler avec plusieurs fournisseurs d’API d’un certain genre (par exemple les plateformes de cloud, les réseaux sociaux, etc.).
Identification : Le pont peut être identifié grâce à une distinction très nette entre une entité de contrôle et plusieurs plateformes différentes dont elle dépend.
Pont entre différents appareils et télécommandes
Dans cet exemple, nous allons voir la séparation entre les classes des télécommandes et celles des appareils qu’elles contrôlent.
Les télécommandes prennent le rôle de l’abstraction et les appareils sont leurs implémentations. Les mêmes télécommandes peuvent manipuler les différents appareils et vice versa grâce à leurs interfaces communes.
Le pont permet de modifier ou même de créer de nouvelles classes sans toucher au code de la hiérarchie opposée.
devices
devices/Device.java: Interface commune à tous les appareils
package refactoring_guru.bridge.example.devices;
public interface Device {
boolean isEnabled();
void enable();
void disable();
int getVolume();
void setVolume(int percent);
int getChannel();
void setChannel(int channel);
void printStatus();
}
devices/Radio.java: Radio
package refactoring_guru.bridge.example.devices;
public class Radio implements Device {
private boolean on = false;
private int volume = 30;
private int channel = 1;
@Override
public boolean isEnabled() {
return on;
}
@Override
public void enable() {
on = true;
}
@Override
public void disable() {
on = false;
}
@Override
public int getVolume() {
return volume;
}
@Override
public void setVolume(int volume) {
if (volume > 100) {
this.volume = 100;
} else if (volume < 0) {
this.volume = 0;
} else {
this.volume = volume;
}
}
@Override
public int getChannel() {
return channel;
}
@Override
public void setChannel(int channel) {
this.channel = channel;
}
@Override
public void printStatus() {
System.out.println("------------------------------------");
System.out.println("| I'm radio.");
System.out.println("| I'm " + (on ? "enabled" : "disabled"));
System.out.println("| Current volume is " + volume + "%");
System.out.println("| Current channel is " + channel);
System.out.println("------------------------------------\n");
}
}
devices/Tv.java: TV
package refactoring_guru.bridge.example.devices;
public class Tv implements Device {
private boolean on = false;
private int volume = 30;
private int channel = 1;
@Override
public boolean isEnabled() {
return on;
}
@Override
public void enable() {
on = true;
}
@Override
public void disable() {
on = false;
}
@Override
public int getVolume() {
return volume;
}
@Override
public void setVolume(int volume) {
if (volume > 100) {
this.volume = 100;
} else if (volume < 0) {
this.volume = 0;
} else {
this.volume = volume;
}
}
@Override
public int getChannel() {
return channel;
}
@Override
public void setChannel(int channel) {
this.channel = channel;
}
@Override
public void printStatus() {
System.out.println("------------------------------------");
System.out.println("| I'm TV set.");
System.out.println("| I'm " + (on ? "enabled" : "disabled"));
System.out.println("| Current volume is " + volume + "%");
System.out.println("| Current channel is " + channel);
System.out.println("------------------------------------\n");
}
}
remotes
remotes/Remote.java: Interface commune à toutes les télécommandes
package refactoring_guru.bridge.example.remotes;
public interface Remote {
void power();
void volumeDown();
void volumeUp();
void channelDown();
void channelUp();
}
remotes/BasicRemote.java: Télécommande basique
package refactoring_guru.bridge.example.remotes;
import refactoring_guru.bridge.example.devices.Device;
public class BasicRemote implements Remote {
protected Device device;
public BasicRemote() {}
public BasicRemote(Device device) {
this.device = device;
}
@Override
public void power() {
System.out.println("Remote: power toggle");
if (device.isEnabled()) {
device.disable();
} else {
device.enable();
}
}
@Override
public void volumeDown() {
System.out.println("Remote: volume down");
device.setVolume(device.getVolume() - 10);
}
@Override
public void volumeUp() {
System.out.println("Remote: volume up");
device.setVolume(device.getVolume() + 10);
}
@Override
public void channelDown() {
System.out.println("Remote: channel down");
device.setChannel(device.getChannel() - 1);
}
@Override
public void channelUp() {
System.out.println("Remote: channel up");
device.setChannel(device.getChannel() + 1);
}
}
remotes/AdvancedRemote.java: Télécommande avancée
package refactoring_guru.bridge.example.remotes;
import refactoring_guru.bridge.example.devices.Device;
public class AdvancedRemote extends BasicRemote {
public AdvancedRemote(Device device) {
super.device = device;
}
public void mute() {
System.out.println("Remote: mute");
device.setVolume(0);
}
}
Demo.java: Code client
package refactoring_guru.bridge.example;
import refactoring_guru.bridge.example.devices.Device;
import refactoring_guru.bridge.example.devices.Radio;
import refactoring_guru.bridge.example.devices.Tv;
import refactoring_guru.bridge.example.remotes.AdvancedRemote;
import refactoring_guru.bridge.example.remotes.BasicRemote;
public class Demo {
public static void main(String[] args) {
testDevice(new Tv());
testDevice(new Radio());
}
public static void testDevice(Device device) {
System.out.println("Tests with basic remote.");
BasicRemote basicRemote = new BasicRemote(device);
basicRemote.power();
device.printStatus();
System.out.println("Tests with advanced remote.");
AdvancedRemote advancedRemote = new AdvancedRemote(device);
advancedRemote.power();
advancedRemote.mute();
device.printStatus();
}
}
OutputDemo.txt: Résultat de l’exécution
Tests with basic remote.
Remote: power toggle
------------------------------------
| I'm TV set.
| I'm enabled
| Current volume is 30%
| Current channel is 1
------------------------------------
Tests with advanced remote.
Remote: power toggle
Remote: mute
------------------------------------
| I'm TV set.
| I'm disabled
| Current volume is 0%
| Current channel is 1
------------------------------------
Tests with basic remote.
Remote: power toggle
------------------------------------
| I'm radio.
| I'm enabled
| Current volume is 30%
| Current channel is 1
------------------------------------
Tests with advanced remote.
Remote: power toggle
Remote: mute
------------------------------------
| I'm radio.
| I'm disabled
| Current volume is 0%
| Current channel is 1
------------------------------------