| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 909cbb9 commit 00028ad
24 files changed
| Original file line number | Diff line number | Diff 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) | ||
| Original file line number | Diff line number | Diff 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() | ||
| Original file line number | Diff line number | Diff 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)) | ||
| Original file line number | Diff line number | Diff 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() | ||
| Original file line number | Diff line number | Diff 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) | ||
| Original file line number | Diff line number | Diff 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() | ||
| Original file line number | Diff line number | Diff 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 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments