Featured image of post CP3 - Builder - Design Pattern From Simple Things

CP3 - Builder - Design Pattern From Simple Things

Building a house involves bringing together many parts, each house has its own specific requirements, you need a builder who can easily implement what you want.

Builder is a creational design pattern: šŸ–¤šŸ¤šŸ¤šŸ¤šŸ¤

Design patterns can often be replaced by built-in language features so some pattern/language don’t need to be implemented anymore. Builder/Python is a good example of that evil!

What is Builder?

Builder is the guy helping you to create object based on your requirements, tell the builder what you want, then he will give the expected outcome

Builder Diagram

Why use Builder?

I don’t know about other languages, but in Python you don’t need it, It looks stupid when you use Builder with Python.

Question: Why Builder is stupid in Python?

Answer: Since Python supports Named Parameters šŸ¤– , the built-in feature is nicer than Builder šŸ‘·ā€ā™‚ļø

Builder is deprecated

When to use Builder?

Question: If I still want to use Builder, when can I use it?

Answer: When you need to create multiple variations of a class

Input:

  • Knowing how to build house parts:
    • Ground Floor
    • First Floor
    • Roof
1
# nothing here

Expected Output:

  • Getting 3 houses:
    • House without Roof
    • Simple House (House without First Floor)
    • Advanced House (House has all parts: Ground Floor, First Floor, Roof)
1
2
3
4
5
6
7
8
9
O
U
--
^
U
--
^
O
U

How to implement Builder?

Non-Builder 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
class NormalHouse:
    def __init__(self, has_ground_floor=False, has_first_floor=False, has_roof=False):
        self.parts = []
        if has_ground_floor:
            ground = "U"
            self.parts.append(ground)
        if has_first_floor:
            first_floor = "O"
            self.parts.append(first_floor)
        if has_roof:
            roof = "^"
            self.parts.append(roof)

    def show_off(self):
        print("\n".join(self.parts[::-1]))


if __name__ == "__main__":
    normal_house = NormalHouse(has_ground_floor=True, has_first_floor=True)
    normal_house.show_off()
    print("--")
    simple_house = NormalHouse(has_ground_floor=True, has_roof=True)
    simple_house.show_off()
    print("--")
    normal_house = NormalHouse(
        has_ground_floor=True, has_first_floor=True, has_roof=True
    )
    normal_house.show_off()

Builder 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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
from abc import abstractmethod


class Builder:
    @property
    @abstractmethod
    def house(self):
        pass

    @abstractmethod
    def build_roof(self):
        pass

    @abstractmethod
    def build_ground_floor(self):
        pass

    @abstractmethod
    def build_first_floor(self):
        pass


class NormalHouseBuilder(Builder):
    def __init__(self):
        self.reset()

    def reset(self):
        self._house = NormalHouse()

    @property
    def house(self):
        house = self._house
        self.reset()
        return house

    def build_roof(self):
        roof = "^"
        self._house.add(roof)

    def build_ground_floor(self):
        ground = "U"
        self._house.add(ground)

    def build_first_floor(self):
        first_floor = "O"
        self._house.add(first_floor)


class NormalHouse:
    def __init__(self):
        self.parts = []

    def add(self, part):
        self.parts.append(part)

    def show_off(self):
        print("\n".join(self.parts[::-1]))


class Director:
    def __init__(self, builder):
        self.builder = builder

    def build_simple_house(self):
        self.builder.build_ground_floor()
        self.builder.build_roof()

    def build_advanced_house(self):
        self.builder.build_ground_floor()
        self.builder.build_first_floor()
        self.builder.build_roof()


if __name__ == "__main__":
    builder = NormalHouseBuilder()
    builder.build_ground_floor()
    builder.build_first_floor()
    builder.house.show_off()
    print("--")
    director = Director(builder)
    director.build_simple_house()
    builder.house.show_off()
    print("--")
    director.build_advanced_house()
    builder.house.show_off()

Source Code

Made with the laziness šŸ¦„
by a busy guy