Skip to content

Commit 49549a2

Browse files
committed
Add Bridge Pattern
1 parent 25f40bf commit 49549a2

39 files changed

+566
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
## Patterns
55

66
- [Strategy](./patterns/behavioural/strategy/README.md)
7+
- [Bridge](./patterns/structural/bridge/README.md)

patterns/structural/__init__.py

Whitespace-only changes.

patterns/structural/bridge/__init__.py

Whitespace-only changes.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import uuid
2+
from io import StringIO
3+
4+
5+
BufferData = StringIO
6+
BufferOutput = str
7+
8+
9+
def generate_id() -> str:
10+
return str(uuid.uuid4())
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from .services import (
2+
YouTubeStreamingService,
3+
YouTubeStreamingServiceWithWebcam,
4+
TwitchStreamingService,
5+
TwitchStreamingServiceWithDSLRCamera,
6+
TwitchStreamingServiceWithWebcam,
7+
)
8+
9+
10+
def main() -> None:
11+
youtube_service = YouTubeStreamingService()
12+
youtube_service.add_device(YouTubeStreamingServiceWithWebcam(quality="720p"))
13+
youtube_service.fill_buffer()
14+
youtube_output = youtube_service.collect_and_close_stream()
15+
print(youtube_output)
16+
17+
twitch_service = TwitchStreamingService()
18+
twitch_service.add_device(TwitchStreamingServiceWithDSLRCamera())
19+
twitch_service.add_device(TwitchStreamingServiceWithWebcam(quality="720p"))
20+
twitch_service.fill_buffer()
21+
twitch_output = twitch_service.collect_and_close_stream()
22+
print(twitch_output)
23+
24+
25+
if __name__ == "__main__":
26+
main()
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from .streaming_service import StreamingService, Quality
2+
from .twitch_stream import (
3+
TwitchStreamingService,
4+
TwitchStreamingServiceWithWebcam,
5+
TwitchStreamingServiceWithDSLRCamera,
6+
)
7+
from .youtube_stream import (
8+
YouTubeStreamingService,
9+
YouTubeStreamingServiceWithWebcam,
10+
YouTubeStreamingServiceWithDSLRCamera,
11+
)
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
from abc import ABC, abstractmethod
2+
from dataclasses import dataclass, field
3+
from typing import List, Literal
4+
from io import StringIO
5+
6+
from .. import BufferData, BufferOutput, generate_id
7+
8+
9+
Quality = Literal["360p", "480p", "720p", "1080p", "2160p"]
10+
11+
12+
@dataclass
13+
class StreamingService(ABC):
14+
devices: List["StreamingService"] = field(default_factory=list)
15+
output: BufferData = field(default_factory=StringIO)
16+
reference: str = field(init=False)
17+
18+
def __post_init__(self):
19+
self.reference = generate_id()
20+
21+
def add_device(self, device: "StreamingService") -> None:
22+
if not isinstance(device, type(self)):
23+
raise ValueError(
24+
f"Only subclasses can be used - {type(device)} is not subclass of {type(self)}"
25+
)
26+
27+
self.devices.append(device)
28+
29+
def retrieve_buffer_data(self) -> List[BufferData]:
30+
return [device.get_buffer_data() for device in self.devices]
31+
32+
@abstractmethod
33+
def fill_buffer(self) -> None:
34+
...
35+
36+
@abstractmethod
37+
def collect_and_close_stream(self) -> BufferOutput:
38+
...
39+
40+
@abstractmethod
41+
def get_buffer_data(self) -> BufferData:
42+
...
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from io import StringIO
2+
from dataclasses import dataclass
3+
4+
from . import StreamingService, Quality
5+
from .. import BufferOutput, BufferData
6+
7+
8+
class TwitchStreamingService(StreamingService):
9+
def fill_buffer(self) -> None:
10+
buffer_data = self.retrieve_buffer_data()
11+
for buffer in buffer_data:
12+
buffer_content = buffer.getvalue()
13+
self.output.write(
14+
f"Received buffer data: {buffer_content}. Sending to Twitch stream: {self.reference}.\n"
15+
)
16+
17+
def collect_and_close_stream(self) -> BufferOutput:
18+
self.output.write(f"Closing Twitch stream with reference {self.reference}.\n")
19+
collected_buffer = self.output.getvalue()
20+
self.output.close()
21+
return collected_buffer
22+
23+
def get_buffer_data(self) -> BufferData:
24+
raise NotImplementedError()
25+
26+
27+
class TwitchStreamingServiceWithDSLRCamera(TwitchStreamingService):
28+
def get_buffer_data(self) -> BufferData:
29+
return StringIO("###DSLRDATA###")
30+
31+
32+
@dataclass
33+
class TwitchStreamingServiceWithWebcam(TwitchStreamingService):
34+
quality: Quality = "1080p"
35+
36+
def get_buffer_data(self) -> BufferData:
37+
return StringIO(f"###WEBCAMDATA at {self.quality}###")
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from io import StringIO
2+
from dataclasses import dataclass
3+
4+
from . import StreamingService, Quality
5+
from .. import BufferOutput, BufferData
6+
7+
8+
class YouTubeStreamingService(StreamingService):
9+
def fill_buffer(self) -> None:
10+
buffer_data = self.retrieve_buffer_data()
11+
for buffer in buffer_data:
12+
buffer_content = buffer.getvalue()
13+
self.output.write(
14+
f"Received buffer data: {buffer_content}. Sending to YouTube stream: {self.reference}.\n"
15+
)
16+
17+
def collect_and_close_stream(self) -> BufferOutput:
18+
self.output.write(f"Closing YouTube stream with reference {self.reference}.\n")
19+
collected_buffer = self.output.getvalue()
20+
self.output.close()
21+
return collected_buffer
22+
23+
def get_buffer_data(self) -> BufferData:
24+
raise NotImplementedError()
25+
26+
27+
class YouTubeStreamingServiceWithDSLRCamera(YouTubeStreamingService):
28+
def get_buffer_data(self) -> BufferData:
29+
return StringIO("###DSLRDATA###")
30+
31+
32+
@dataclass
33+
class YouTubeStreamingServiceWithWebcam(YouTubeStreamingService):
34+
quality: Quality = "1080p"
35+
36+
def get_buffer_data(self) -> BufferData:
37+
return StringIO(f"###WEBCAMDATA at {self.quality}###")
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import uuid
2+
from io import StringIO
3+
4+
5+
BufferData = StringIO
6+
BufferOutput = str
7+
8+
9+
def generate_id() -> str:
10+
return str(uuid.uuid4())

0 commit comments

Comments
 (0)