|
11 | 11 | https://python-3-patterns-idioms-test.readthedocs.io/en/latest/Fronting.html
|
12 | 12 |
|
13 | 13 | *TL;DR
|
14 |
| -Provides an interface to resource that is expensive to duplicate. |
| 14 | +Add functionality to a resource without changing its interface. |
15 | 15 | """
|
16 | 16 |
|
17 |
| -import time |
18 | 17 |
|
| 18 | +class Subject: |
| 19 | + """ |
| 20 | + As mentioned in the document, interfaces of both RealSubject and Proxy should |
| 21 | + be the same, because the client should be able to use RealSubject or Proxy with |
| 22 | + no code change. |
| 23 | + """ |
19 | 24 |
|
20 |
| -class SalesManager: |
21 |
| - def talk(self): |
22 |
| - print("Sales Manager ready to talk") |
| 25 | + def do_the_job(self, user): |
| 26 | + raise NotImplementedError() |
23 | 27 |
|
24 | 28 |
|
25 |
| -class Proxy: |
| 29 | +class RealSubject(Subject): |
| 30 | + """ |
| 31 | + This is the main job doer. External services like payment gateways can be a |
| 32 | + good example. |
| 33 | + """ |
| 34 | + |
| 35 | + def do_the_job(self, user): |
| 36 | + print(f'> I am doing the job for {user}') |
| 37 | + |
| 38 | + |
| 39 | +class Proxy(Subject): |
26 | 40 | def __init__(self):
|
27 |
| - self.busy = 'No' |
28 |
| - self.sales = None |
29 |
| - |
30 |
| - def talk(self): |
31 |
| - print("Proxy checking for Sales Manager availability") |
32 |
| - if self.busy == 'No': |
33 |
| - self.sales = SalesManager() |
34 |
| - time.sleep(0.1) |
35 |
| - self.sales.talk() |
36 |
| - else: |
37 |
| - time.sleep(0.1) |
38 |
| - print("Sales Manager is busy") |
| 41 | + self._real_subject = RealSubject() |
39 | 42 |
|
| 43 | + def do_the_job(self, user): |
| 44 | + """ |
| 45 | + logging and controlling access are some examples of proxy usages. |
| 46 | + """ |
40 | 47 |
|
41 |
| -class NoTalkProxy(Proxy): |
42 |
| - def talk(self): |
43 |
| - print("Proxy checking for Sales Manager availability") |
44 |
| - time.sleep(0.1) |
45 |
| - print("This Sales Manager will not talk to you", "whether he/she is busy or not") |
| 48 | + print(f'[log] Doing the job for {user} is requested.') |
| 49 | + |
| 50 | + if user == 'admin': |
| 51 | + self._real_subject.do_the_job(user) |
| 52 | + else: |
| 53 | + print(f'[log] I can do the job just for `admins`.') |
46 | 54 |
|
47 | 55 |
|
48 | 56 | if __name__ == '__main__':
|
49 |
| - p = Proxy() |
50 |
| - p.talk() |
51 |
| - p.busy = 'Yes' |
52 |
| - p.talk() |
53 |
| - p = NoTalkProxy() |
54 |
| - p.talk() |
55 |
| - p.busy = 'Yes' |
56 |
| - p.talk() |
57 |
| - |
58 |
| -### OUTPUT ### |
59 |
| -# Proxy checking for Sales Manager availability |
60 |
| -# Sales Manager ready to talk |
61 |
| -# Proxy checking for Sales Manager availability |
62 |
| -# Sales Manager is busy |
63 |
| -# Proxy checking for Sales Manager availability |
64 |
| -# This Sales Manager will not talk to you whether he/she is busy or not |
65 |
| -# Proxy checking for Sales Manager availability |
66 |
| -# This Sales Manager will not talk to you whether he/she is busy or not |
| 57 | + proxy = Proxy() |
| 58 | + proxy.do_the_job('admin') |
| 59 | + proxy.do_the_job('anonymous') |
| 60 | + |
| 61 | + |
| 62 | +OUTPUT = """ |
| 63 | +[log] Doing the job for admin is requested. |
| 64 | +> I am doing the job for admin |
| 65 | +[log] Doing the job for anonymous is requested. |
| 66 | +[log] I can do the job just for `admins`. |
| 67 | +""" # noqa |
0 commit comments