-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathbuilder_facets.py
More file actions
103 lines (76 loc) · 3.22 KB
/
builder_facets.py
File metadata and controls
103 lines (76 loc) · 3.22 KB
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
"""Builder pattern example: building complicated object using multiple builders.
Note: This builder violates OCP because whenever you need to add a sub-builder, you need
to also add it to the parent builder.
"""
from typing import Optional
class Person:
"""Person class recording the person's address and employment info."""
def __init__(self) -> None:
"""Create a `Person` object with address and employment info unset."""
# address
self.street_address: Optional[str] = None
self.postcode: Optional[str] = None
self.city: Optional[str] = None
# employment info
self.company_name: Optional[str] = None
self.position: Optional[str] = None
self.annual_income: Optional[int] = None
class PersonBuilder:
"""Builder to build a person.
Contains sub-builders to build the person's job and address.
"""
def __init__(self, person: Optional[Person] = None) -> None:
"""Create a `PersonBuilder` with `person` as a starting template if provided."""
if person is None:
self.person = Person()
else:
self.person = person
@property
def works(self) -> "PersonJobBuilder":
"""Return a sub-builder to build the person's job."""
return PersonJobBuilder(self.person)
@property
def lives(self) -> "PersonAddressBuilder":
"""Return a sub-builder to build the person's address."""
return PersonAddressBuilder(self.person)
def build(self) -> Person:
"""Return the `Person` object that is built."""
return self.person
class PersonJobBuilder(PersonBuilder):
"""Sub-builder to build the person's job.
Inherits `works` and `lives` properties, and `build` method from `PersonBuilder`.
"""
def __init__(self, person: Person):
"""Create a job sub-builder for the specified `person`."""
super().__init__(person)
def at(self, company_name: str) -> "PersonJobBuilder":
"""Set the person's company name."""
self.person.company_name = company_name
return self
def as_a(self, position: str) -> "PersonJobBuilder":
"""Set the person's job position."""
self.person.position = position
return self
def earning(self, annual_income: int) -> "PersonJobBuilder":
"""Set the person's annual income."""
self.person.annual_income = annual_income
return self
class PersonAddressBuilder(PersonBuilder):
"""Sub-builder to build the person's address.
Inherits `works` and `lives` properties, and `build` method from `PersonBuilder`.
"""
def __init__(self, person: Person):
"""Create an address sub-builder for the specified `person`."""
super().__init__(person)
def at(self, street_address: str) -> "PersonAddressBuilder":
"""Set the person's street address."""
self.person.street_address = street_address
return self
def with_postcode(self, postcode: str) -> "PersonAddressBuilder":
"""Set the person's post code."""
self.person.postcode = postcode
return self
def in_city(self, city: str) -> "PersonAddressBuilder":
"""Set the person's city."""
self.person.city = city
return self