Vending Machine (Factory) is a creational design pattern:
š¤š¤š¤š¤š¤
Although widely used, (Simple) Factory
is not part of the GoF Design Pattern. It’s a term for a class creating objects without requiring any concrete classes.
Factory
is too vague for me, so I use Vending Machine
instead! Vending Machine is the same as Factory, but it’s more friendly :)
What is Vending Machine?
Beverage Vending Machine is a store holding a variety of beverages(Pepsi
, Coke
, Monster
)
Just enter beverage ID(1
, 2
, 3
) to Beverage Vending Machine, then Beverage Vending Machine will return your beverage.
Why use Vending Machine?
It makes finding your beverage easier!
Question: I hate the Beverage Vending Machine, but I want to buy a Coke
right now because I’m bloating.
Answer: You can find your Coke
by searching in stores. If a store doesn’t sell it, try to find it again by going to another store, try again until you find it š
When to use Vending Machine?
Question: When do I go to the Beverage Vending Machine
?
Answer: When you need a beverage Pepsi, Coke or Monster
, right?
- Having a menu of beverages:
Pepsi (ID = 1)
Coke (ID = 2)
Monster (ID = 3)
- Beverages are being sold.
- Knowing the beverage you need to buy
Coke
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
import abc
# Input 1: Having a menu of beverages:
class MENU:
PEPSI = 1
COKE = 2
MONSTER = 3
class Beverage(metaclass=abc.ABCMeta):
id = ""
carbon_dioxide = 0
# @abc.abstractmethod means: in the concrete class, The method have to re-defined
@abc.abstractmethod
def make_burp(self):
return ""
# Input 2: Beverages are being sold.
class Pepsi(Beverage):
id = MENU.PEPSI
carbon_dioxide = 3
def make_burp(self):
return f"B{'U' * self.carbon_dioxide}RP"
# Input 2: Beverages are being sold.
class Coke(Beverage):
id = MENU.COKE
carbon_dioxide = 2
def make_burp(self):
return f"BU{'R' * self.carbon_dioxide}P"
# Input 2: Beverages are being sold.
class Monster(Beverage):
id = MENU.MONSTER
carbon_dioxide = 1
def make_burp(self):
return f"BURP"
|
Expected Output:
- Get a beverage
Coke
- Drink your beverage and make a burp
BURRP
- Get all carbonated_beverages
1
2
3
4
5
6
|
generate a beverage by id
<Coke object>
BURRP
generate all carbonated beverages
[<Pepsi object>, <Coke object>]
|
How to implement Vending Machine?
Non-Vending Machine implementation:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
if __name__ == "__main__":
print("generate a beverage by id")
beverage = None
for beverage_cls in [Pepsi, Coke, Monster]:
# Input 3: Knowing the beverage you need to buy.
if MENU.COKE == beverage_cls.id:
beverage = beverage_cls()
# Expected Output 1: Get a beverage
print(beverage)
# Expected Output 2: Drink your beverage and make a burp
print(beverage.make_burp())
print("generate all carbonated beverages")
carbonated_beverages = []
for beverage_cls in [Pepsi, Coke, Monster]:
if beverage_cls.carbon_dioxide > 1:
carbonated_beverages.append(beverage_cls())
print(carbonated_beverages)
|
Vending Machine implementation:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
class BeverageVendingMachine:
@property
def subclasses(self):
# [<class 'Pepsi'>, <class 'Coke'>, <class 'Monster'>]
return Beverage.__subclasses__()
@property
def subclass_mapping(self):
# {1: <class 'Pepsi'>, 2: <class 'Coke'>, 3: <class 'Monster'>}
return {beverage.id: beverage for beverage in self.subclasses}
def generate(self, key):
subclass = self.subclass_mapping[key]
instance = subclass()
return instance
@property
def generate_carbonated_beverages(self):
return [subclass() for subclass in self.subclasses if subclass.carbon_dioxide > 1]
if __name__ == "__main__":
beverage_vending_machine = BeverageVendingMachine()
print("generate a beverage by id")
# Input 3: Knowing the beverage you need to buy.
coke = beverage_vending_machine.generate(MENU.COKE)
# Expected Output 1: Get a beverage
print(coke)
# Expected Output 2: Drink your beverage and make a burp
print(coke.make_burp())
print("generate all carbonated beverages")
carbonated_beverages = beverage_vending_machine.generate_carbonated_beverages
print(carbonated_beverages)
|
Source Code