Skip to content

Commit 4e2c29d

Browse files
Adapter Patterns
1 parent c05911b commit 4e2c29d

File tree

2 files changed

+153
-0
lines changed

2 files changed

+153
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
class Point:
2+
def __init__(self, x, y):
3+
self.y = y
4+
self.x = x
5+
6+
7+
def draw_point(p):
8+
print('.', end='')
9+
10+
11+
# ^^ you are given this
12+
13+
# vv you are working with this
14+
class Line:
15+
def __init__(self, start, end):
16+
self.end = end
17+
self.start = start
18+
19+
20+
class Rectangle(list):
21+
""" Represented as a list of lines. """
22+
23+
def __init__(self, x, y, width, height):
24+
super().__init__()
25+
self.append(Line(Point(x, y), Point(x + width, y)))
26+
self.append(Line(Point(x + width, y), Point(x + width, y + height)))
27+
self.append(Line(Point(x, y), Point(x, y + height)))
28+
self.append(Line(Point(x, y + height), Point(x + width, y + height)))
29+
30+
31+
class LineToPointAdapter(list):
32+
count = 0
33+
34+
def __init__(self, line):
35+
self.count += 1
36+
print(f'{self.count}: Generating points for line '
37+
f'[{line.start.x},{line.start.y}]→'
38+
f'[{line.end.x},{line.end.y}]')
39+
40+
left = min(line.start.x, line.end.x)
41+
right = max(line.start.x, line.end.x)
42+
top = min(line.start.y, line.end.y)
43+
bottom = min(line.start.y, line.end.y)
44+
45+
if right - left == 0:
46+
for y in range(top, bottom):
47+
self.append(Point(left, y))
48+
elif line.end.y - line.start.y == 0:
49+
for x in range(left, right):
50+
self.append(Point(x, top))
51+
52+
53+
54+
55+
def draw(rcs):
56+
print("\n\n--- Drawing some stuff ---\n")
57+
for rc in rcs:
58+
for line in rc:
59+
adapter = LineToPointAdapter(line)
60+
for p in adapter:
61+
draw_point(p)
62+
63+
if __name__ == '__main__':
64+
rs = [
65+
Rectangle(1, 1, 10, 10),
66+
Rectangle(3, 3, 6, 6)
67+
]
68+
draw(rs)
69+
draw(rs)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
class Point:
2+
def __init__(self, x, y):
3+
self.y = y
4+
self.x = x
5+
6+
7+
def draw_point(p):
8+
print('.', end='')
9+
10+
11+
# ^^ you are given this
12+
13+
# vv you are working with this
14+
class Line:
15+
def __init__(self, start, end):
16+
self.end = end
17+
self.start = start
18+
19+
20+
class Rectangle(list):
21+
""" Represented as a list of lines. """
22+
23+
def __init__(self, x, y, width, height):
24+
super().__init__()
25+
self.append(Line(Point(x, y), Point(x + width, y)))
26+
self.append(Line(Point(x + width, y), Point(x + width, y + height)))
27+
self.append(Line(Point(x, y), Point(x, y + height)))
28+
self.append(Line(Point(x, y + height), Point(x + width, y + height)))
29+
30+
31+
class LineToPointAdapter:
32+
count = 0
33+
cache = {}
34+
35+
def __init__(self, line):
36+
self.h = hash(line)
37+
if self.h in self.cache:
38+
return
39+
40+
super().__init__()
41+
self.count += 1
42+
print(f'{self.count}: Generating points for line ' +
43+
f'[{line.start.x},{line.start.y}]→[{line.end.x},{line.end.y}]')
44+
45+
left = min(line.start.x, line.end.x)
46+
right = max(line.start.x, line.end.x)
47+
top = min(line.start.y, line.end.y)
48+
bottom = min(line.start.y, line.end.y)
49+
50+
points = []
51+
52+
if right - left == 0:
53+
for y in range(top, bottom):
54+
points.append(Point(left, y))
55+
elif line.end.y - line.start.y == 0:
56+
for x in range(left, right):
57+
points.append(Point(x, top))
58+
59+
self.cache[self.h] = points
60+
61+
def __iter__(self):
62+
return iter(self.cache[self.h])
63+
64+
def draw(rcs):
65+
print('Drawing some rectangles...')
66+
for rc in rcs:
67+
for line in rc:
68+
adapter = LineToPointAdapter(line)
69+
for p in adapter:
70+
draw_point(p)
71+
print('\n')
72+
73+
74+
if __name__ == '__main__':
75+
rs = [
76+
Rectangle(1, 1, 10, 10),
77+
Rectangle(3, 3, 6, 6)
78+
]
79+
80+
draw(rs)
81+
draw(rs)
82+
83+
# can define your own hashes or use the defaults
84+
print(hash(Line(Point(1, 1), Point(10, 10))))

0 commit comments

Comments
 (0)