Structural_Bridge
✅ Bridge
- decouple abstract and implementation
- bridge can connect abstract and concrete
✅ Structure
1
2
3
4
bridge
Abstraction -----> Implementor
| |
RefinedAbstraction ConcreteImplementor
- client uses
Abstraction Implementorwill be interfaceAbstractionwill haveImplementoras attribute- so,
Abstractionis dependent onImplementor
👀 Remote controller and Device example
1
2
3
Abstraction(Remote) -----> Implementor(Device)
| |
RefinedAbstraction(RemoteController) ConcreteImplementor(TV, Radio)
✔️ Implementation: Device
- do not know anything about remote,
- do not know anything about abstraction
1
2
3
4
5
6
public interface Device {
void turnOn();
void turnOff();
void setVolume(int volume);
boolean isEnabled();
}
✔️ ConcreteImplemention : TV
1
2
3
public class TV implements Device{
//override the methods
}
✔️ Abstraction: Remote
RemotehasDeviceas field- 👉🏻
Remoteis dependent onDevice - 👉🏻
Abstractionis dependent onImplementation - 👉🏻 This is the bridge between
AbstractionandImplementation
1
2
3
4
5
6
7
8
9
public abstract class Remote {
private Device device; //abstraction is dependent on implementation
protected Remote(Device device) {
this.device = device;
}
public abstract void power();
}
✔️ RefinedAbstraction: BasicRemote
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class BasicRemote extends Remote{
public BasicRemote(Device device) {
super(device);
}
@Override
public void power() {
if(device.isEnabled()){
device.turnOff();
}else{
device.turnOn();
}
}
}
✔️ Client code
1
2
3
Device tv = new TV();
Remote basicRemote = new BasicRemote(tv);
basicRemote.power();
👍🏻
- can create as many
Abstraction(remote controller)class without interruptingImplementation - can create as many
Implementation(devices)class without interruptingAbstraction
👀 MessageSender exmaple
✔️ Implementation: MessageSender
1
2
3
public interface MessageSender {
void sendMessage(String message);
}
✔️ ConcreteImplemention : EmailSender, SMSSender
1
2
3
4
5
6
7
8
9
10
11
12
13
public class EmailSender implements MessageSender{
@Override
public void sendMessage(String message) {
System.out.println("Email");
}
}
public class SMSSender implements MessageSender{
@Override
public void sendMessage(String message) {
System.out.println("SMS");
}
}
✔️ Abstraction: Message
1
2
3
4
5
6
7
8
9
public abstract class Message {
private MessageSender messageSender; //bridge between abstract, implementation
protected Message(MessageSender messageSender) {
this.messageSender = messageSender;
}
public abstract void send(String message);
}
✔️ RefinedAbstraction: TextMessage, EncryptedMessage
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class TextMessage extends Message{
protected TextMessage(MessageSender messageSender) {
super(messageSender);
}
@Override
public void send(String message) {
System.out.println("text message");
}
}
public class EncryptedMessage extends Message{
protected EncryptedMessage(MessageSender messageSender) {
super(messageSender);
}
@Override
public void send(String message) {
System.out.println("EncryptedMessage");
}
}
✔️ Client code
AbstractionandImplementation을 이리저리 갈아끼울 수 있음
1
2
3
4
5
6
7
8
9
10
11
public class App {
public static void main(String[] args) {
MessageSender email = new EmailSender();
MessageSender sms = new SMSSender();
Message textEmail = new TextMessage(email);
Message encryptedEmail = new EncryptedMessage(email);
Message textSMS = new TextMessage(sms);
Message encryptedSMS = new EncryptedMessage(sms);
}
}
👍🏻
- 👍🏻 decouple abstract and implementation
- can modify abstract code without modifying concrete implementation
- 👉🏻 open closed principle
🛠️
JDBCallows you to usedriver(implemtation)- but change of driver will not change
code, database(abstract)
This post is licensed under CC BY 4.0 by the author.
