Skip to content

Commit 393d783

Browse files
authored
Merge pull request faif#321 from h4ppysmile/patch-1
enhance top description
2 parents 184b1a4 + 0f16335 commit 393d783

File tree

2 files changed

+73
-41
lines changed

2 files changed

+73
-41
lines changed

append_output.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ output_marker='OUTPUT = """'
1010
# get everything (excluding part between `output_marker` and the end of the file)
1111
# into `src` var
1212
src=$(sed -n -e "/$output_marker/,\$!p" "$1")
13-
output=$(python "$1")
13+
output=$(python3 "$1")
1414

1515
echo "$src" > $1
1616
echo -e "\n" >> $1

patterns/structural/proxy.py

Lines changed: 72 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,87 @@
11
"""
2+
*What is this pattern about?
3+
Proxy is used in places where you want to add functionality to a class without
4+
changing its interface. The main class is called `Real Subject`. A client should
5+
use the proxy or the real subject without any code change, so both must have the
6+
same interface. Logging and controlling access to the real subject are some of
7+
the proxy pattern usages.
8+
9+
*References:
10+
https://refactoring.guru/design-patterns/proxy/python/example
11+
https://python-3-patterns-idioms-test.readthedocs.io/en/latest/Fronting.html
12+
213
*TL;DR
3-
Provides an interface to resource that is expensive to duplicate.
14+
Add functionality or logic (e.g. logging, caching, authorization) to a resource
15+
without changing its interface.
416
"""
517

6-
import time
718

19+
class Subject:
20+
"""
21+
As mentioned in the document, interfaces of both RealSubject and Proxy should
22+
be the same, because the client should be able to use RealSubject or Proxy with
23+
no code change.
24+
25+
Not all times this interface is necessary. The point is the client should be
26+
able to use RealSubject or Proxy interchangeably with no change in code.
27+
"""
28+
29+
def do_the_job(self, user):
30+
raise NotImplementedError()
831

9-
class SalesManager:
10-
def talk(self):
11-
print("Sales Manager ready to talk")
1232

33+
class RealSubject(Subject):
34+
"""
35+
This is the main job doer. External services like payment gateways can be a
36+
good example.
37+
"""
1338

14-
class Proxy:
39+
def do_the_job(self, user):
40+
print(f'I am doing the job for {user}')
41+
42+
43+
class Proxy(Subject):
1544
def __init__(self):
16-
self.busy = 'No'
17-
self.sales = None
18-
19-
def talk(self):
20-
print("Proxy checking for Sales Manager availability")
21-
if self.busy == 'No':
22-
self.sales = SalesManager()
23-
time.sleep(0.1)
24-
self.sales.talk()
45+
self._real_subject = RealSubject()
46+
47+
def do_the_job(self, user):
48+
"""
49+
logging and controlling access are some examples of proxy usages.
50+
"""
51+
52+
print(f'[log] Doing the job for {user} is requested.')
53+
54+
if user == 'admin':
55+
self._real_subject.do_the_job(user)
2556
else:
26-
time.sleep(0.1)
27-
print("Sales Manager is busy")
57+
print(f'[log] I can do the job just for `admins`.')
58+
59+
60+
def client(job_doer, user):
61+
job_doer.do_the_job(user)
62+
63+
def main():
64+
"""
65+
>>> proxy = Proxy()
66+
67+
>>> real_subject = RealSubject()
68+
69+
>>> client(proxy, 'admin')
70+
[log] Doing the job for admin is requested.
71+
I am doing the job for admin
72+
73+
>>> client(proxy, 'anonymous')
74+
[log] Doing the job for anonymous is requested.
75+
[log] I can do the job just for `admins`.
2876
77+
>>> client(real_subject, 'admin')
78+
I am doing the job for admin
2979
30-
class NoTalkProxy(Proxy):
31-
def talk(self):
32-
print("Proxy checking for Sales Manager availability")
33-
time.sleep(0.1)
34-
print("This Sales Manager will not talk to you", "whether he/she is busy or not")
80+
>>> client(real_subject, 'anonymous')
81+
I am doing the job for anonymous
82+
"""
3583

3684

3785
if __name__ == '__main__':
38-
p = Proxy()
39-
p.talk()
40-
p.busy = 'Yes'
41-
p.talk()
42-
p = NoTalkProxy()
43-
p.talk()
44-
p.busy = 'Yes'
45-
p.talk()
46-
47-
### OUTPUT ###
48-
# Proxy checking for Sales Manager availability
49-
# Sales Manager ready to talk
50-
# Proxy checking for Sales Manager availability
51-
# Sales Manager is busy
52-
# Proxy checking for Sales Manager availability
53-
# This Sales Manager will not talk to you whether he/she is busy or not
54-
# Proxy checking for Sales Manager availability
55-
# This Sales Manager will not talk to you whether he/she is busy or not
86+
import doctest
87+
doctest.testmod()

0 commit comments

Comments
 (0)