Total Complexity | 56 |
Total Lines | 265 |
Duplicated Lines | 0 % |
Changes | 5 | ||
Bugs | 1 | Features | 0 |
Complex classes like Address often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Address, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
17 | class Address |
||
18 | { |
||
19 | public const TAG_NAME = 'address'; |
||
20 | |||
21 | private ?string $streetName = null; |
||
22 | private ?string $number = null; |
||
23 | private ?string $box = null; |
||
24 | private ?string $postalCode = null; |
||
25 | private ?string $locality = null; |
||
26 | private ?string $countryCode = 'BE'; |
||
27 | |||
28 | /** |
||
29 | * @throws BpostInvalidLengthException |
||
30 | */ |
||
31 | public function __construct( |
||
32 | ?string $streetName = null, |
||
33 | ?string $number = null, |
||
34 | ?string $box = null, |
||
35 | ?string $postalCode = null, |
||
36 | ?string $locality = null, |
||
37 | ?string $countryCode = null |
||
38 | ) { |
||
39 | if ($streetName !== null) $this->setStreetName($streetName); |
||
40 | if ($number !== null) $this->setNumber($number); |
||
41 | if ($box !== null) $this->setBox($box); |
||
42 | if ($postalCode !== null) $this->setPostalCode($postalCode); |
||
43 | if ($locality !== null) $this->setLocality($locality); |
||
44 | if ($countryCode !== null) $this->setCountryCode($countryCode); |
||
45 | } |
||
46 | |||
47 | /** |
||
48 | * @throws BpostInvalidLengthException |
||
49 | */ |
||
50 | public function setBox(?string $box): void |
||
51 | { |
||
52 | if ($box === null) { |
||
53 | $this->box = null; |
||
54 | return; |
||
55 | } |
||
56 | |||
57 | $max = 8; |
||
58 | if (mb_strlen($box) > $max) { |
||
59 | throw new BpostInvalidLengthException('box', mb_strlen($box), $max); |
||
60 | } |
||
61 | $this->box = $box; |
||
62 | } |
||
63 | public function getBox(): ?string |
||
64 | { |
||
65 | return $this->box; |
||
66 | } |
||
67 | |||
68 | /** |
||
69 | * @throws BpostInvalidLengthException |
||
70 | */ |
||
71 | public function setCountryCode(string $countryCode): void |
||
72 | { |
||
73 | $max = 2; |
||
74 | if (mb_strlen($countryCode) > $max) { |
||
75 | throw new BpostInvalidLengthException('countryCode', mb_strlen($countryCode), $max); |
||
76 | } |
||
77 | $this->countryCode = strtoupper($countryCode); |
||
78 | } |
||
79 | public function getCountryCode(): ?string |
||
80 | { |
||
81 | return $this->countryCode; |
||
82 | } |
||
83 | |||
84 | /** |
||
85 | * @throws BpostInvalidLengthException |
||
86 | */ |
||
87 | public function setLocality(string $locality): void |
||
88 | { |
||
89 | $max = 40; |
||
90 | if (mb_strlen($locality) > $max) { |
||
91 | throw new BpostInvalidLengthException('locality', mb_strlen($locality), $max); |
||
92 | } |
||
93 | $this->locality = $locality; |
||
94 | } |
||
95 | public function getLocality(): ?string |
||
96 | { |
||
97 | return $this->locality; |
||
98 | } |
||
99 | |||
100 | /** |
||
101 | * @throws BpostInvalidLengthException |
||
102 | */ |
||
103 | public function setNumber(string $number): void |
||
104 | { |
||
105 | $max = 8; |
||
106 | if (mb_strlen($number) > $max) { |
||
107 | throw new BpostInvalidLengthException('number', mb_strlen($number), $max); |
||
108 | } |
||
109 | $this->number = $number; |
||
110 | } |
||
111 | public function getNumber(): ?string |
||
112 | { |
||
113 | return $this->number; |
||
114 | } |
||
115 | |||
116 | /** |
||
117 | * @throws BpostInvalidLengthException |
||
118 | */ |
||
119 | public function setPostalCode(string $postalCode): void |
||
126 | } |
||
127 | public function getPostalCode(): ?string |
||
128 | { |
||
129 | return $this->postalCode; |
||
130 | } |
||
131 | |||
132 | /** |
||
133 | * @throws BpostInvalidLengthException |
||
134 | */ |
||
135 | public function setStreetName(string $streetName): void |
||
142 | } |
||
143 | public function getStreetName(): ?string |
||
144 | { |
||
145 | return $this->streetName; |
||
146 | } |
||
147 | |||
148 | /** |
||
149 | * @throws \DOMException |
||
150 | */ |
||
151 | public function toXML(DOMDocument $document, ?string $prefix = 'common'): DOMElement |
||
152 | { |
||
153 | // <common:address> |
||
154 | $address = $document->createElement( |
||
155 | XmlHelper::getPrefixedTagName(self::TAG_NAME, $prefix) |
||
156 | ); |
||
157 | |||
158 | // <common:streetName>, <common:number>, <common:box> |
||
159 | if ($this->streetName !== null) { |
||
160 | $address->appendChild($document->createElement( |
||
161 | XmlHelper::getPrefixedTagName('streetName', $prefix), |
||
162 | $this->streetName |
||
163 | )); |
||
164 | } |
||
165 | if ($this->number !== null) { |
||
166 | $address->appendChild($document->createElement( |
||
167 | XmlHelper::getPrefixedTagName('number', $prefix), |
||
168 | $this->number |
||
169 | )); |
||
170 | } |
||
171 | if ($this->box !== null) { |
||
172 | $address->appendChild($document->createElement( |
||
173 | XmlHelper::getPrefixedTagName('box', $prefix), |
||
174 | $this->box |
||
175 | )); |
||
176 | } |
||
177 | |||
178 | // <common:postalCode>, <common:locality>, <common:countryCode> |
||
179 | if ($this->postalCode !== null) { |
||
180 | $address->appendChild($document->createElement( |
||
181 | XmlHelper::getPrefixedTagName('postalCode', $prefix), |
||
182 | $this->postalCode |
||
183 | )); |
||
184 | } |
||
185 | if ($this->locality !== null) { |
||
186 | $address->appendChild($document->createElement( |
||
187 | XmlHelper::getPrefixedTagName('locality', $prefix), |
||
188 | $this->locality |
||
189 | )); |
||
190 | } |
||
191 | if ($this->countryCode !== null) { |
||
192 | $address->appendChild($document->createElement( |
||
193 | XmlHelper::getPrefixedTagName('countryCode', $prefix), |
||
194 | $this->countryCode |
||
195 | )); |
||
196 | } |
||
197 | |||
198 | return $address; |
||
199 | } |
||
200 | |||
201 | /** |
||
202 | * @throws BpostInvalidLengthException |
||
203 | */ |
||
204 | public static function createFromXML(SimpleXMLElement $xml): Address |
||
205 | { |
||
206 | $address = new static(); |
||
207 | if (isset($xml->streetName) && $xml->streetName != '') { |
||
208 | $address->setStreetName((string) $xml->streetName); |
||
209 | } |
||
210 | if (isset($xml->number) && $xml->number != '') { |
||
211 | $address->setNumber((string) $xml->number); |
||
212 | } |
||
213 | if (isset($xml->box) && $xml->box != '') { |
||
214 | $address->setBox((string) $xml->box); |
||
215 | } |
||
216 | if (isset($xml->postalCode) && $xml->postalCode != '') { |
||
217 | $address->setPostalCode((string) $xml->postalCode); |
||
218 | } |
||
219 | if (isset($xml->locality) && $xml->locality != '') { |
||
220 | $address->setLocality((string) $xml->locality); |
||
221 | } |
||
222 | if (isset($xml->countryCode) && $xml->countryCode != '') { |
||
223 | $address->setCountryCode((string) $xml->countryCode); |
||
224 | } |
||
225 | return $address; |
||
226 | } |
||
227 | |||
228 | /** |
||
229 | * @throws \DOMException |
||
230 | */ |
||
231 | private function streetToXML(DOMDocument $document, string $prefix, DOMElement $address): void |
||
|
|||
232 | { |
||
233 | if ($this->streetName !== null) { |
||
234 | $address->appendChild( |
||
235 | $document->createElement(XmlHelper::getPrefixedTagName('streetName', $prefix), $this->streetName) |
||
236 | ); |
||
237 | } |
||
238 | } |
||
239 | |||
240 | /** |
||
241 | * @throws \DOMException |
||
242 | */ |
||
243 | private function localityToXML(DOMDocument $document, string $prefix, DOMElement $address): void |
||
253 | ); |
||
254 | } |
||
255 | } |
||
256 | |||
257 | /** |
||
258 | * @throws \DOMException |
||
259 | */ |
||
260 | private function countryToXML(DOMDocument $document, string $prefix, DOMElement $address): void |
||
265 | ); |
||
266 | } |
||
267 | } |
||
268 | |||
269 | /** |
||
270 | * @throws \DOMException |
||
271 | */ |
||
272 | private function streetNumbersToXML(DOMDocument $document, string $prefix, DOMElement $address): void |
||
282 | ); |
||
283 | } |
||
284 | } |
||
285 | } |
This check looks for private methods that have been defined, but are not used inside the class.