|
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