diff --git a/behavioral/strategy.py b/behavioral/strategy.py index bf008fe98..a84af02da 100644 --- a/behavioral/strategy.py +++ b/behavioral/strategy.py @@ -33,42 +33,70 @@ Enables selecting an algorithm at runtime. """ -import types - class StrategyExample: - - def __init__(self, func=None): - self.name = 'Strategy Example 0' - if func is not None: - self.execute = types.MethodType(func, self) - def execute(self): - print(self.name) + print('In execute default') - -def execute_replacement1(self): - print(self.name + ' from execute 1') +class Strat1(StrategyExample): + def execute(self): + print('In execute 1') -def execute_replacement2(self): - print(self.name + ' from execute 2') +class Strat2(StrategyExample): + def execute(self): + print('In execute 2') if __name__ == '__main__': strat0 = StrategyExample() - - strat1 = StrategyExample(execute_replacement1) - strat1.name = 'Strategy Example 1' - - strat2 = StrategyExample(execute_replacement2) - strat2.name = 'Strategy Example 2' + strat1 = Strat1() + strat2 = Strat2() strat0.execute() strat1.execute() strat2.execute() -### OUTPUT ### -# Strategy Example 0 -# Strategy Example 1 from execute 1 -# Strategy Example 2 from execute 2 + +# ============================================================== + + +# import types +# +# +# class StrategyExample: +# +# def __init__(self, func=None): +# self.name = 'Strategy Example 0' +# if func is not None: +# self.execute = types.MethodType(func, self) +# +# def execute(self): +# print(self.name) +# +# +# def execute_replacement1(self): +# print(self.name + ' from execute 1') +# +# +# def execute_replacement2(self): +# print(self.name + ' from execute 2') +# +# +# if __name__ == '__main__': +# strat0 = StrategyExample() +# +# strat1 = StrategyExample(execute_replacement1) +# strat1.name = 'Strategy Example 1' +# +# strat2 = StrategyExample(execute_replacement2) +# strat2.name = 'Strategy Example 2' +# +# strat0.execute() +# strat1.execute() +# strat2.execute() +# +# ### OUTPUT ### +# # Strategy Example 0 +# # Strategy Example 1 from execute 1 +# # Strategy Example 2 from execute 2 diff --git a/creational/deliberate_practice_abstract_factory.py b/creational/deliberate_practice_abstract_factory.py new file mode 100644 index 000000000..dc3f75e0d --- /dev/null +++ b/creational/deliberate_practice_abstract_factory.py @@ -0,0 +1,195 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +*What is this pattern about? + +In Java and other languages, the Abstract Factory Pattern serves to provide an interface for +creating related/dependent objects without need to specify their +actual class. + +The idea is to abstract the creation of objects depending on business +logic, platform choice, etc. + +In Python, the interface we use is simply a callable, which is "builtin" interface +in Python, and in normal circumstances we can simply use the class itself as +that callable, because classes are first class objects in Python. + +*What does this example do? +This particular implementation abstracts the creation of a pet and +does so depending on the factory we chose (Dog or Cat, or random_animal) +This works because both Dog/Cat and random_animal respect a common +interface (callable for creation and .speak()). +Now my application can create pets abstractly and decide later, +based on my own criteria, dogs over cats. + +*Where is the pattern used practically? + +*References: +https://sourcemaking.com/design_patterns/abstract_factory +http://ginstrom.com/scribbles/2007/10/08/design-patterns-python-style/ + +*TL;DR80 +Provides a way to encapsulate a group of individual factories. +""" + + +# __Q: Change this to use a factory, so can even have it show a random animal each time! P1t180815 P1t180909 P1t181109 P2t190107 P4t200704 P5t270319 P6t570517 rm4.5 tp5 + + +class PetShop(object): + + """A pet shop""" + + def __init__(self, pet): + """pet_factory is our abstract factory. We can set it at will.""" + + self.pet = pet + + def show_pet(self): + """Creates and shows a pet using the abstract factory""" + + print(f"We have a lovely {self.pet}") + print(f"It says {self.pet.speak()}") + + +class Pet: + def speak(self): return f"NotImplemented-{self}" + def __str__(self): return "AbstractPet" + + +class Dog(Pet): + + def speak(self): + return "woof" + + def __str__(self): + return "Dog" + + +class Cat(Pet): + + def speak(self): + return "meow" + + def __str__(self): + return "Cat" + + +# Additional Factories + + + +# Show pets with various factories +if __name__ == "__main__": + + # A Shop that sells only cats + cat_shop = PetShop(Cat()) + cat_shop.show_pet() + print("") + + # A Shop that sells only dogs + cat_shop = PetShop(Dog()) + cat_shop.show_pet() + print("") + + # A shop that sells random animals? + # shop = PetShop(random_animal) + # for i in range(3): + # shop.show_pet() + # print("=" * 20) + +### OUTPUT ### +# We have a lovely Cat +# It says meow +# +# We have a lovely Dog +# It says woof +# ==================== +# We have a lovely Cat +# It says meow +# ==================== +# We have a lovely Cat +# It says meow +# ==================== + + + + +# +# import random +# +# +# class PetShop(object): +# +# """A pet shop""" +# +# def __init__(self, animal_factory=None): +# """pet_factory is our abstract factory. We can set it at will.""" +# +# self.pet_factory = animal_factory +# +# def show_pet(self): +# """Creates and shows a pet using the abstract factory""" +# +# pet = self.pet_factory() +# print("We have a lovely {}".format(pet)) +# print("It says {}".format(pet.speak())) +# +# +# class Dog(object): +# +# def speak(self): +# return "woof" +# +# def __str__(self): +# return "Dog" +# +# +# class Cat(object): +# +# def speak(self): +# return "meow" +# +# def __str__(self): +# return "Cat" +# +# +# # Additional factories: +# +# Make is_random! + + +# # Create a random animal +# def random_animal(): +# """Let's be dynamic!""" +# return random.choice([Dog, Cat])() +# +# +# # Show pets with various factories +# if __name__ == "__main__": +# +# # A Shop that sells only cats +# cat_shop = PetShop(Cat) +# cat_shop.show_pet() +# print("") +# +# # A shop that sells random animals +# shop = PetShop(random_animal) +# for i in range(3): +# shop.show_pet() +# print("=" * 20) +# +# ### OUTPUT ### +# # We have a lovely Cat +# # It says meow +# # +# # We have a lovely Dog +# # It says woof +# # ==================== +# # We have a lovely Cat +# # It says meow +# # ==================== +# # We have a lovely Cat +# # It says meow +# # ====================