CP2 - Comparison between Factories: Simple Factory & Factory Method & Abstract Factory - Design Pattern From Simple Things
Simple Factory is da best, Factory Method and Abstract Factory are cumbersome, complicated and stupid?
Vending Machine Method (Factory Method) is a creational design pattern: 🖤🤍🤍🤍🤍 Abstract Vending Machine(Abstract Factory) is a creational design pattern: 🖤🖤🤍🤍🤍
What is Vending Machine(Simple Factory)?
It’s a way to create:
- a class
Vending Machinecreating objects without requiring any concrete classesRegularBeverage,DietBeverage.
Vending Machine looks handsome and famous, but it’s not a member of the GoF family. I’ve talked about it before.
What is Vending Machine Method(Factory Method)?
It’s a way to create:
- a Parent(Super) class
Vending Machine- with an abstractmethod
def create_beverage: return Noneto generate the specific product. - with a common method
def show_infoto return the product’s info
- with an abstractmethod
- Sub(Child/Inherited) classes
RegularVendingMachine, DietVendingMachinewill redefine what productRegularBeverage(),DietBeverage()will be returned.
What is Abstract Vending Machine(Abstract Factory)?
same as Machine Method(Factory Method), but it can generate many
beverage, snackkind of products instead of only onebeverage
It’s a way to create:
- a Parent(Super) class
Vending Machinedefines abstractmethod(s)def create_beverage: return None, def create_snack: return Noneto generate the product. - Sub(Child/Inherited) classes
RegularVendingMachine, DietVendingMachinewill redefine what productRegularBeverage,DietBeverage,RegularSnack,DietSnackwill be returned.
Why use Vending Machine?
It makes generating the products RegularBeverage, DietBeverage easier!
Why use Vending Machine Method?
Question: Can you edit the product classesBeverage,RegularBeverage,DietBeverage (is it yours)?
Answer: Yes
- Just using Vending Machine is enough! It may require editing the product classes a bit, but it’s nicer. Don’t use Vending Machine Method if you don’t really need it.
Answer: No
- Okay, Vending Machine Method is helpful when you can’t edit the product classes (it’s not your classes, can’t touch it).
- Vending Machine Method lets a class defer (postpone, delay) instantiation to subclasses.
- Your subclasses
RegularVendingMachine,DietVendingMachine,...will:- inherit your superclass
VendingMachine - redefines the generation method
def create_beveragein its own way - then subclasses generate products
RegularBeverage, DietBeverage, ...that have common methodsdef show_info, properties of superclass without redefinition.
- inherit your superclass
Why use Abstract Vending Machine?
When you want to use Vending Machine Method, but you can not!
Because have more Beverage, Snack than one Beverage(Regular,Diet) kind of product need to be handled
When products are:
Beverage, Snackcan use Vending Machine MethodRegularBeverage, DietBeveragecan use Vending Machine MethodRegularSnack, DietSnackcan use Vending Machine Method
When products are:
RegularBeverage, DietBeverage, RegularSnack, DietSnackcan use Abstract Vending Machine
When to use Vending Machine?
Input:
from abc import ABC, abstractmethod
class Beverage(ABC):
@abstractmethod
def make_burp(self):
pass
# Q:Can you edit the product classes? A:Yes.
# Since this class can be edited, we add `def show_info` here for later use
def show_info(self):
info = {
**self.__dict__,
"type": type(self),
"burp_sound": self.make_burp(),
}
return info
class RegularBeverage(Beverage):
def make_burp(self):
return "BURP"
class DietBeverage(Beverage):
def make_burp(self):
return "Diet - BURP"
Expected Output:
{'type': <class 'RegularBeverage'>, 'burp_sound': 'BURP'}
{'type': <class 'DietBeverage'>, 'burp_sound': 'Diet - BURP'}
When to use Vending Machine Method?
Input:
from abc import ABC, abstractmethod
class Beverage(ABC):
@abstractmethod
def make_burp(self):
pass
# Q:Can you edit the product classes? A:No.
# Since this class is immutable, we can not add `def show_info` here, we have to find another way like, wrap from the outside!
class RegularBeverage(Beverage):
def make_burp(self):
return "BURP"
class DietBeverage(Beverage):
def make_burp(self):
return "Diet - BURP"
Expected Output:
{'type': <class 'RegularBeverage'>, 'burp_sound': 'BURP'}
{'type': <class 'DietBeverage'>, 'burp_sound': 'Diet - BURP'}
When to use Abstract Vending Machine?
Input:
from abc import ABC, abstractmethod
class Beverage(ABC):
@abstractmethod
def make_burp(self):
pass
class Snack(ABC):
@abstractmethod
def make_thirsty(self):
pass
class RegularBeverage(Beverage):
def make_burp(self):
return "BURP"
class RegularSnack(Snack):
def make_thirsty(self):
return "I'm thirsty"
class DietBeverage(Beverage):
def make_burp(self):
return "Diet - BURP"
class DietSnack(Snack):
def make_thirsty(self):
return "Diet - I'm thirsty"
Expected Output:
{'type': <class 'RegularBeverage'>, 'burp_sound': 'BURP'}
- "BURP"
{'type': <class 'RegularSnack'>, 'thirsty_sound': "I'm thirsty"}
- "I'm thirsty"
{'type': <class 'DietBeverage'>, 'burp_sound': 'Diet - BURP'}
- "Diet - BURP"
{'type': <class 'DietSnack'>, 'thirsty_sound': "Diet - I'm thirsty"}
- "Diet - I'm thirsty"
How to implement Vending Machine?
class BeverageVendingMachine:
def generate(self, beverage_type):
if beverage_type == "Regular":
return RegularBeverage()
elif beverage_type == "Diet":
return DietBeverage()
if __name__ == "__main__":
for beverage_type in ("Regular", "Diet"):
beverage = BeverageVendingMachine().generate(beverage_type)
print(beverage.show_info())
How to implement Vending Machine Method?
class VendingMachine(ABC):
@abstractmethod
def create_beverage(self):
pass
def show_info(self):
beverage = self.create_beverage()
info = {
**beverage.__dict__,
"type": type(beverage),
"burp_sound": beverage.make_burp(),
}
return info
class RegularVendingMachine(VendingMachine):
def create_beverage(self):
return RegularBeverage()
class DietVendingMachine(VendingMachine):
def create_beverage(self):
return DietBeverage()
if __name__ == "__main__":
for vending_machine in (RegularVendingMachine(), DietVendingMachine()):
print(vending_machine.show_info())
Source Code: Vending Machine Method
How to implement Abstract Vending Machine?
class AbstractVendingMachine(ABC):
@abstractmethod
def create_beverage(self):
pass
@abstractmethod
def create_snack(self):
pass
def show_beverage_info(self):
beverage = self.create_beverage()
info = {
**beverage.__dict__,
"type": type(beverage),
"burp_sound": beverage.make_burp(),
}
return info
def show_snack_info(self):
snack = self.create_snack()
info = {
**snack.__dict__,
"type": type(snack),
"thirsty_sound": snack.make_thirsty(),
}
return info
class RegularVendingMachine(AbstractVendingMachine):
def create_beverage(self):
return RegularBeverage()
def create_snack(self):
return RegularSnack()
class DietVendingMachine(AbstractVendingMachine):
def create_beverage(self):
return DietBeverage()
def create_snack(self):
return DietSnack()
if __name__ == "__main__":
for vending_machine in (RegularVendingMachine(), DietVendingMachine()):
beverage_vending_machine = vending_machine.create_beverage()
print(vending_machine.show_beverage_info())
print(f' - "{beverage_vending_machine.make_burp()}"')
snack_vending_machine = vending_machine.create_snack()
print(vending_machine.show_snack_info())
print(f' - "{snack_vending_machine.make_thirsty()}"')
Related posts
-
Verify vs Cert: The Python Requests Handbook
Understanding SSL/TLS in Python Requests: The 'verify' and 'cert' arguments explained with interactive animations.
-
SP7 - Proxy - Learn Design Pattern From Simple Things
The boss wants the employees to focus on work and not get distracted by social media. So he decides to block some websites on the corporate network during working hours.
-
SP6 - Object Pool - Learn Design Pattern From Simple Things
Producing planes on a large scale is expensive, but fortunately the manufactured raw parts are always stored in the pool, thereby reducing duplication in the production process.
-
SP5 - Facade - Learn Design Pattern From Simple Things
There are many departments in the building and you feel confused! By opening the entrances from the facade according to purposes, you simply follow the pre-arranged flow.