Skip to content

Commit f89db31

Browse files
authored
Add proxy design pattern
1 parent 8ac9047 commit f89db31

File tree

1 file changed

+84
-0
lines changed

1 file changed

+84
-0
lines changed

structural_patterns/proxy.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
from dataclasses import dataclass, field
2+
from abc import ABC, abstractmethod
3+
from random import choice
4+
5+
6+
# The interface of a remote service
7+
class ThirdPartyYoutubeLib(ABC):
8+
@abstractmethod
9+
def list_videos(self):
10+
pass
11+
12+
@abstractmethod
13+
def get_video_info(self, id):
14+
pass
15+
16+
@abstractmethod
17+
def download_video(self, id):
18+
pass
19+
20+
21+
class ThirdPartyYoutubeClass(ThirdPartyYoutubeLib):
22+
def list_videos(self):
23+
print('Getting the video list from Youtube API')
24+
25+
def get_video_info(self, id):
26+
print(f'Get metadata from Youtube API about a video, with id: {id}')
27+
28+
def download_video(self, id):
29+
print(f'Download a video file from YouTube API, with id: {id}')
30+
31+
32+
@dataclass
33+
class CachedYoutubeClass(ThirdPartyYoutubeLib):
34+
service: ThirdPartyYoutubeLib
35+
# Reference: https://stackoverflow.com/questions/53632152/why-cant-dataclasses-have-mutable-defaults-in-their-class-attributes-declaratio
36+
list_cache: list = field(default_factory=list)
37+
video_cache: str = None
38+
need_reset: bool = False
39+
40+
def list_videos(self):
41+
if self.list_cache == [] or self.need_reset:
42+
self.list_cache = self.service.list_videos()
43+
44+
return self.list_cache
45+
46+
def get_video_info(self, id):
47+
if self.video_cache == None or self.need_reset:
48+
self.video_cache = self.service.get_video_info(id)
49+
50+
return self.video_cache
51+
52+
def download_video(self, id):
53+
if not self.downdload_exists(id) or self.need_reset:
54+
self.service.download_video(id)
55+
56+
def _download_exists(self):
57+
return choice(True, False)
58+
59+
60+
@dataclass
61+
class YoutubeManager:
62+
service: ThirdPartyYoutubeLib
63+
64+
def render_video_page(self, id):
65+
info = self.service.get_video_info(id)
66+
67+
return info
68+
69+
def render_list_panel(self):
70+
video_list = self.service.list_videos()
71+
72+
return video_list
73+
74+
def react_on_user_input(self, id):
75+
self.render_video_page(id)
76+
self.render_list_panel()
77+
78+
79+
if __name__ == '__main__':
80+
concrete_youtube_class = ThirdPartyYoutubeClass()
81+
proxy_youtube_class = CachedYoutubeClass(concrete_youtube_class)
82+
83+
manager = YoutubeManager(proxy_youtube_class)
84+
manager.react_on_user_input(id='xc343fgg')

0 commit comments

Comments
 (0)