Skip to content

Commit 00028ad

Browse files
author
Sakis Kasampalis
committed
initial commit
1 parent 909cbb9 commit 00028ad

24 files changed

+1470
-0
lines changed

abstract_factory.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# http://ginstrom.com/scribbles/2007/10/08/design-patterns-python-style/
2+
3+
"""Implementation of the abstract factory pattern"""
4+
5+
import random
6+
7+
class PetShop:
8+
"""A pet shop"""
9+
10+
def __init__(self, animal_factory=None):
11+
"""pet_factory is our abstract factory.
12+
We can set it at will."""
13+
14+
self.pet_factory = animal_factory
15+
16+
def show_pet(self):
17+
"""Creates and shows a pet using the
18+
abstract factory"""
19+
20+
pet = self.pet_factory.get_pet()
21+
print("This is a lovely", pet)
22+
print("It says", pet.speak())
23+
print("It eats", self.pet_factory.get_food())
24+
25+
# Stuff that our factory makes
26+
27+
class Dog:
28+
def speak(self):
29+
return "woof"
30+
def __str__(self):
31+
return "Dog"
32+
33+
class Cat:
34+
def speak(self):
35+
return "meow"
36+
def __str__(self):
37+
return "Cat"
38+
39+
# Factory classes
40+
41+
class DogFactory:
42+
def get_pet(self):
43+
return Dog()
44+
def get_food(self):
45+
return "dog food"
46+
47+
class CatFactory:
48+
def get_pet(self):
49+
return Cat()
50+
def get_food(self):
51+
return "cat food"
52+
53+
# Create the proper family
54+
def get_factory():
55+
"""Let's be dynamic!"""
56+
return random.choice([DogFactory, CatFactory])()
57+
58+
# Show pets with various factories
59+
if __name__== "__main__":
60+
shop = PetShop()
61+
for i in range(3):
62+
shop.pet_factory = get_factory()
63+
shop.show_pet()
64+
print("=" * 20)

adapter.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# http://ginstrom.com/scribbles/2008/11/06/generic-adapter-class-in-python/
2+
3+
import os
4+
5+
class Dog(object):
6+
def __init__(self):
7+
self.name = "Dog"
8+
9+
def bark(self):
10+
return "woof!"
11+
12+
class Cat(object):
13+
def __init__(self):
14+
self.name = "Cat"
15+
16+
def meow(self):
17+
return "meow!"
18+
19+
class Human(object):
20+
def __init__(self):
21+
self.name = "Human"
22+
23+
def speak(self):
24+
return "'hello'"
25+
26+
class Car(object):
27+
def __init__(self):
28+
self.name = "Car"
29+
30+
def make_noise(self, octane_level):
31+
return "vroom%s" % ("!" * octane_level)
32+
33+
class Adapter(object):
34+
"""
35+
Adapts an object by replacing methods.
36+
Usage:
37+
dog = Dog
38+
dog = Adapter(dog, dict(make_noise=dog.bark))
39+
"""
40+
def __init__(self, obj, adapted_methods):
41+
"""We set the adapted methods in the object's dict"""
42+
self.obj = obj
43+
self.__dict__.update(adapted_methods)
44+
45+
def __getattr__(self, attr):
46+
"""All non-adapted calls are passed to the object"""
47+
return getattr(self.obj, attr)
48+
49+
def main():
50+
objects = []
51+
dog = Dog()
52+
objects.append(Adapter(dog, dict(make_noise=dog.bark)))
53+
cat = Cat()
54+
objects.append(Adapter(cat, dict(make_noise=cat.meow)))
55+
human = Human()
56+
objects.append(Adapter(human, dict(make_noise=human.speak)))
57+
car = Car()
58+
car_noise = lambda : car.make_noise(3)
59+
objects.append(Adapter(car, dict(make_noise=car_noise)))
60+
61+
for obj in objects:
62+
print("A", obj.name, "goes", obj.make_noise())
63+
64+
if __name__ == "__main__":
65+
main()

borg.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
class Borg:
2+
__shared_state = {}
3+
4+
def __init__(self):
5+
self.__dict__ = self.__shared_state
6+
self.state = 'Running'
7+
8+
def __str__(self):
9+
return self.state
10+
11+
if __name__ == '__main__':
12+
rm1 = Borg()
13+
rm2 = Borg()
14+
15+
print('rm1 state: {}'.format(rm1))
16+
print('rm2 state: {}'.format(rm2))
17+
18+
rm2.state = 'Idle'
19+
20+
print('rm1 state: {}'.format(rm1))
21+
print('rm2 state: {}'.format(rm2))
22+
23+
print('rm1 id: {}', id(rm1))
24+
print('rm2 id: {}', id(rm2))

bridge.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# http://en.wikibooks.org/wiki/Computer_Science_Design_Patterns/Bridge_Pattern#Python
2+
3+
# ConcreteImplementor 1/2
4+
class DrawingAPI1:
5+
def drawCircle(self, x, y, radius):
6+
print('API1.circle at {}:{} radius {}'.format(x, y, radius))
7+
8+
# ConcreteImplementor 2/2
9+
class DrawingAPI2:
10+
def drawCircle(self, x, y, radius):
11+
print('API2.circle at {}:{} radius {}'.format(x, y, radius))
12+
13+
# Refined Abstraction
14+
class CircleShape:
15+
def __init__(self, x, y, radius, drawingAPI):
16+
self.__x = x
17+
self.__y = y
18+
self.__radius = radius
19+
self.__drawingAPI = drawingAPI
20+
21+
# low-level i.e. Implementation specific
22+
def draw(self):
23+
self.__drawingAPI.drawCircle(self.__x, self.__y, self.__radius)
24+
25+
# high-level i.e. Abstraction specific
26+
def resizeByPercentage(self, pct):
27+
self.__radius *= pct
28+
29+
def main():
30+
shapes = (
31+
CircleShape(1, 2, 3, DrawingAPI1()),
32+
CircleShape(5, 7, 11, DrawingAPI2())
33+
)
34+
35+
for shape in shapes:
36+
shape.resizeByPercentage(2.5)
37+
shape.draw()
38+
39+
if __name__ == "__main__":
40+
main()

builder.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#!/usr/bin/python
2+
# -*- coding : utf-8 -*-
3+
4+
"""
5+
@author: Diogenes Augusto Fernandes Herminio <diofeher@gmail.com>
6+
https://gist.github.com/420905#file_builder_python.py
7+
"""
8+
9+
# Director
10+
class Director(object):
11+
def __init__(self):
12+
self.builder = None
13+
14+
def construct_building(self):
15+
self.builder.new_building()
16+
self.builder.build_floor()
17+
self.builder.build_size()
18+
19+
def get_building(self):
20+
return self.builder.building
21+
22+
# Abstract Builder
23+
class Builder(object):
24+
def __init__(self):
25+
self.building = None
26+
27+
def new_building(self):
28+
self.building = Building()
29+
30+
# Concrete Builder
31+
class BuilderHouse(Builder):
32+
def build_floor(self):
33+
self.building.floor ='One'
34+
35+
def build_size(self):
36+
self.building.size = 'Big'
37+
38+
class BuilderFlat(Builder):
39+
def build_floor(self):
40+
self.building.floor ='More than One'
41+
42+
def build_size(self):
43+
self.building.size = 'Small'
44+
45+
# Product
46+
class Building(object):
47+
def __init__(self):
48+
self.floor = None
49+
self.size = None
50+
51+
def __repr__(self):
52+
return 'Floor: %s | Size: %s' % (self.floor, self.size)
53+
54+
# Client
55+
if __name__== "__main__":
56+
director = Director()
57+
director.builder = BuilderHouse()
58+
director.construct_building()
59+
building = director.get_building()
60+
print(building)
61+
director.builder = BuilderFlat()
62+
director.construct_building()
63+
building = director.get_building()
64+
print(building)

chain.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# http://www.testingperspective.com/wiki/doku.php/collaboration/chetan/designpatternsinpython/chain-of-responsibilitypattern
2+
3+
class Handler:
4+
def successor(self, successor):
5+
self.successor = successor
6+
7+
class ConcreteHandler1(Handler):
8+
def handle(self, request):
9+
if request > 0 and request <= 10:
10+
print("in handler1")
11+
else:
12+
self.successor.handle(request)
13+
14+
class ConcreteHandler2(Handler):
15+
def handle(self, request):
16+
if request > 10 and request <= 20:
17+
print("in handler2")
18+
else:
19+
self.successor.handle(request)
20+
21+
class ConcreteHandler3(Handler):
22+
def handle(self, request):
23+
if request > 20 and request <= 30:
24+
print("in handler3")
25+
else:
26+
print('end of chain, no handler for {}'.format(request))
27+
28+
class Client:
29+
def __init__(self):
30+
h1 = ConcreteHandler1()
31+
h2 = ConcreteHandler2()
32+
h3 = ConcreteHandler3()
33+
34+
h1.successor(h2)
35+
h2.successor(h3)
36+
37+
requests = [2, 5, 14, 22, 18, 3, 35, 27, 20]
38+
for request in requests:
39+
h1.handle(request)
40+
41+
if __name__== "__main__":
42+
client = Client()

command.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import os
2+
3+
class MoveFileCommand(object):
4+
def __init__(self, src, dest):
5+
self.src = src
6+
self.dest = dest
7+
8+
def execute(self):
9+
self()
10+
11+
def __call__(self):
12+
print('renaming {} to {}'.format(self.src, self.dest))
13+
os.rename(self.src, self.dest)
14+
15+
def undo(self):
16+
print('renaming {} to {}'.format(self.dest, self.src))
17+
os.rename(self.dest, self.src)
18+
19+
20+
if __name__ == "__main__":
21+
undo_stack = []
22+
ren1 = MoveFileCommand('foo.txt', 'bar.txt')
23+
ren2 = MoveFileCommand('bar.txt', 'baz.txt')
24+
25+
# commands are just pushed into the command stack
26+
for cmd in ren1, ren2:
27+
undo_stack.append(cmd)
28+
29+
# they can be executed later on will
30+
for cmd in undo_stack:
31+
cmd.execute() # foo.txt is now renamed to baz.txt
32+
33+
# and can also be undone on will
34+
for cmd in undo_stack:
35+
undo_stack.pop().undo() # Now it's bar.txt
36+
undo_stack.pop().undo() # and back to foo.txt

0 commit comments

Comments
 (0)