Wzorzec Most – czyli jak oddzielić abstrakcję od implementacji, dzięki czemu można modyfikować te dwa elementy niezależnie od siebie. To w przybliżeniu opis wzorca. Ale niestety nie ułatwia to zrozumienia całej idei, a więc zacznijmy od problemu z jakim można się spotkać.

Problem na przykładzie klawiatury i komputera
Załóżmy, że mamy do zaimplementowania kilka modeli klawiatur komputerowych. Klawiatury muszą oczywiście pracować współpracować z wieloma komputerami. Jednym z podejść byłoby stworzenie każdej opcji:
abstract class Keyboard {
handleKey(String key);
}
class LenovoComputerLogitechKeyboard extends Keyboard{
LenovoComputer lenovoComputer;
handleKey(String key){
\\ handling key logic based on lenovoComputer
}
}
class LenovoComputerKeychronKeyboard extends Keyboard{
LenovoComputer lenovoComputer;
handleKey(String key){
\\ handling key logic based on lenovoComputer
}
}
class DellComputerLogitechKeyboard extends Keyboard{
DellComputer dellComputer;
handleKey(String key){
\\ handling key logic based on dellComputer
}
}
class DellComputerKeychronKeyboard extends Keyboard{
DellComputer dellComputer;
handleKey(String key){
\\ handling key logic based on dellComputer
}
}Jest to jakieś rozwiązanie. Ale rodzą się przynajmniej dwa problemy:
1. Logika najczęściej musi być gdzieś kopiowana (pomiędzy tymi samymi klawiaturami dla innych komputerów) lub też trzymana w jakichś oddzielnych miejscach (co też nie jest super rozwiązaniem)
2. Jeśli dojdzie jeszcze jeden komputer, to należy stworzyć implementację dla każdej klawiatury (przykładowo LenovoComputerRazerKeyboard, DellComputerRazerKeyboard)
Lepsze rozwiązanie
Lepszym rozwiązaniem wydaje się stworzenie odpowiednich abstrakcji – ustalenie kontraktu. Czyli ustalamy czym się charakteryzuje komputer:
interface Computer {
onKeyPressEvent(String key);
}I teraz klawiatura ma operować na tej abstrakcji:
abstract class Keyboard {
Computer computer;
Keyboard(Computer computer){
this.computer = computer;
}
handleKey(String key);
}Dzięki temu tworzenie klawiatur nie jest uzależnione od dostępnych komputerów – każda klawiatura potrafi obsłużyć każdy komputer:
class LogitechKeyboard extends Keyboard {
Computer computer;
LogitechKeyboard(Computer computer){
super(computer);
}
handleKey(String key){
if(key == 'FN'){
//specific logic for Logitech keyboard
} else{
computer.onKeyPressEvent(key)
}
}
}Teraz dodanie następnej klawiatury, nie powoduje konieczności dodania implementacji tylu klawiatur ile mamy typów komputerów. I w drugą stronę – dodanie komputera nie powoduje konieczności implementacji każdej klawiatury dla tego komputera.
