-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbridge.ts
More file actions
130 lines (109 loc) · 3.62 KB
/
Copy pathbridge.ts
File metadata and controls
130 lines (109 loc) · 3.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// Bridge Design Pattern Example
// Abstraction
class RemoteControl {
// 🔗 BRIDGE: This property holds the reference to the implementor (the bridge connection)
protected device: DeviceImplementor;
// 🔗 BRIDGE: Constructor establishes the bridge by accepting an implementor
constructor(device: DeviceImplementor) {
this.device = device; // Bridge is created here
}
togglePower(): void {
// 🔗 BRIDGE: Using the bridge to call implementor methods
if (this.device.isEnabled()) {
this.device.disable();
} else {
this.device.enable();
}
}
volumeUp(): void {
// 🔗 BRIDGE: Delegating to implementor through the bridge
this.device.setVolume(this.device.getVolume() + 10);
}
volumeDown(): void {
// 🔗 BRIDGE: Delegating to implementor through the bridge
this.device.setVolume(this.device.getVolume() - 10);
}
}
// Refined Abstraction
class AdvancedRemoteControl extends RemoteControl {
mute(): void {
// 🔗 BRIDGE: Using the inherited bridge to access implementor
this.device.setVolume(0);
}
}
// 🔗 BRIDGE INTERFACE: This interface IS the bridge - it defines the contract
// that connects the abstraction (RemoteControl) to implementations (TV, Radio)
interface DeviceImplementor {
enable(): void;
disable(): void;
isEnabled(): boolean;
setVolume(volume: number): void;
getVolume(): number;
}
// Concrete Implementors
class TV implements DeviceImplementor {
private on: boolean = false;
private volume: number = 20;
enable(): void {
this.on = true;
console.log("TV is turned ON");
}
disable(): void {
this.on = false;
console.log("TV is turned OFF");
}
isEnabled(): boolean {
return this.on;
}
setVolume(volume: number): void {
this.volume = Math.max(0, Math.min(100, volume));
console.log(`TV volume set to ${this.volume}`);
}
getVolume(): number {
return this.volume;
}
}
class Radio implements DeviceImplementor {
private on: boolean = false;
private volume: number = 15;
enable(): void {
this.on = true;
console.log("Radio is ON");
}
disable(): void {
this.on = false;
console.log("Radio is OFF");
}
isEnabled(): boolean {
return this.on;
}
setVolume(volume: number): void {
this.volume = Math.max(0, Math.min(100, volume));
console.log(`Radio volume: ${this.volume}`);
}
getVolume(): number {
return this.volume;
}
}
// Usage
function runBridgeDemo() {
const tv = new TV();
// 🔗 BRIDGE: Creating the bridge connection - passing implementor to abstraction
const remote = new RemoteControl(tv);
remote.togglePower(); // TV is turned ON
remote.volumeUp(); // TV volume set to 30
remote.volumeDown(); // TV volume set to 20
const radio = new Radio();
// 🔗 BRIDGE: Another bridge connection with different implementor
const advancedRemote = new AdvancedRemoteControl(radio);
advancedRemote.togglePower(); // Radio is ON
advancedRemote.volumeUp(); // Radio volume: 25
advancedRemote.mute(); // Radio volume: 0
}
runBridgeDemo();
/*
Example applications of the Bridge pattern:
- UI frameworks: separating abstractions like GUI windows from platform-dependent rendering APIs.
- Remotes for smart devices: allowing various kinds of remotes to control various kinds of devices.
- Persistence layer: decoupling repository interfaces from their underlying storage implementations (SQL, Mongo, file, etc).
*/