Complex classes like Shipment 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
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 Shipment, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
16 | class Shipment |
||
17 | { |
||
18 | const TYPE_DLV = 'DLV'; |
||
19 | const TYPE_VAL = 'VAL'; |
||
20 | const TYPE_HAL = 'HAL'; |
||
21 | const TYPE_BLT = 'BLT'; |
||
22 | |||
23 | /** |
||
24 | * Unique Number for each day (Required). |
||
25 | * Cannot be Null |
||
26 | * Correspond to (refNo) |
||
27 | * |
||
28 | * @var string |
||
29 | */ |
||
30 | private $referenceNumber; |
||
31 | /** |
||
32 | * DLV for normal Shipments for other special cases we will provide. |
||
33 | * Mandatory Value from DLV,VAL,HAL or BLT |
||
34 | * Correspond to (shipType) |
||
35 | * |
||
36 | * @var string |
||
37 | */ |
||
38 | private $type; |
||
39 | /** |
||
40 | * No. of Pieces. |
||
41 | * Mandatory Integer |
||
42 | * Correspond to (PCs) |
||
43 | * |
||
44 | * @var int |
||
45 | */ |
||
46 | private $itemsCount = 1; |
||
47 | /** |
||
48 | * Weight of the Shipment |
||
49 | * It has to be numeric, but will be converted string. |
||
50 | * |
||
51 | * @var int |
||
52 | */ |
||
53 | private $weight = 0; |
||
54 | |||
55 | /** Optional Properties */ |
||
56 | |||
57 | /** |
||
58 | * Id. |
||
59 | * Optional |
||
60 | * Correspond to (idNo) |
||
61 | * |
||
62 | * @var string |
||
63 | */ |
||
64 | private $id; |
||
65 | /** |
||
66 | * Description of the items present in shipment. |
||
67 | * Optional |
||
68 | * Correspond to (itemDesc) |
||
69 | * |
||
70 | * @var string |
||
71 | */ |
||
72 | private $description; |
||
73 | /** |
||
74 | * Shipment Sent Date. |
||
75 | * Optional |
||
76 | * |
||
77 | * @var string |
||
78 | */ |
||
79 | private $sentDate; |
||
80 | |||
81 | /** Value Properties */ |
||
82 | |||
83 | /** |
||
84 | * Value Either 0 or greater than 0 in case of COD. |
||
85 | * Required if CASH ON DELIVERY |
||
86 | * Correspond to (codAmt) |
||
87 | * |
||
88 | * @var int |
||
89 | */ |
||
90 | private $cashOnDelivery = 0; |
||
91 | |||
92 | /** |
||
93 | * A default currency for value, insurance and customs . |
||
94 | * |
||
95 | * This value will be used when either of value, insurance or customs are set without specifying specific currency. |
||
96 | * |
||
97 | * @var string |
||
98 | */ |
||
99 | private $defaultCurrency; |
||
100 | /** |
||
101 | * Carriage Value. |
||
102 | * Optional |
||
103 | * Correspond to (carrValue) |
||
104 | * |
||
105 | * @var string |
||
106 | */ |
||
107 | private $value; |
||
108 | /** |
||
109 | * Carriage Currency. |
||
110 | * Optional |
||
111 | * Correspond to (carrCurr) |
||
112 | * |
||
113 | * @var string |
||
114 | */ |
||
115 | private $valueCurrency; |
||
116 | /** |
||
117 | * Customs Value. |
||
118 | * Optional |
||
119 | * Correspond to (custVal) |
||
120 | * |
||
121 | * @var string |
||
122 | */ |
||
123 | private $customs; |
||
124 | /** |
||
125 | * Customs Currency. |
||
126 | * Optional |
||
127 | * Correspond to (custCurr) |
||
128 | * |
||
129 | * @var string |
||
130 | */ |
||
131 | private $customsCurrency; |
||
132 | /** |
||
133 | * Insurance Value. |
||
134 | * Optional |
||
135 | * Correspond to (insrAmt) |
||
136 | * |
||
137 | * @var string |
||
138 | */ |
||
139 | private $insurance; |
||
140 | /** |
||
141 | * Insurance Currency. |
||
142 | * Optional |
||
143 | * Correspond to (insrCurr) |
||
144 | * |
||
145 | * @var string |
||
146 | */ |
||
147 | private $insuranceCurrency; |
||
148 | |||
149 | /** |
||
150 | * Preferred Delivery date in case of future or delayed delivery. |
||
151 | * Optional |
||
152 | * Correspond to (prefDelvDate) |
||
153 | * |
||
154 | * @var string |
||
155 | */ |
||
156 | private $deliveryDate; |
||
157 | /** |
||
158 | * Google GPS points separated by comma for delivery to customer by Google maps |
||
159 | * Optional |
||
160 | * |
||
161 | * @var string |
||
162 | */ |
||
163 | private $gpsPoints; |
||
164 | |||
165 | /** Related Objects */ |
||
166 | |||
167 | /** |
||
168 | * Customer associated with the shipment. |
||
169 | * |
||
170 | * @var \Alhoqbani\SmsaWebService\Models\Customer |
||
171 | */ |
||
172 | private $customer; |
||
173 | /** |
||
174 | * Shipper associated with the shipment. |
||
175 | * |
||
176 | * @var \Alhoqbani\SmsaWebService\Models\Shipper |
||
177 | */ |
||
178 | private $shipper; |
||
179 | |||
180 | /** |
||
181 | * Shipment constructor. |
||
182 | * |
||
183 | * @param string $referenceNumber |
||
184 | * @param \Alhoqbani\SmsaWebService\Models\Customer $customer |
||
185 | * @param string $type |
||
186 | */ |
||
187 | public function __construct( |
||
196 | |||
197 | public function getTypeObject(string $passKey): AbstractStructBase |
||
237 | |||
238 | /** |
||
239 | * Determines the SOAP type and method used to create the shipment |
||
240 | * |
||
241 | * @return string |
||
242 | */ |
||
243 | public function getServiceMethod(): string |
||
248 | |||
249 | /** |
||
250 | * Create an instance of the shipment type. |
||
251 | * |
||
252 | * If we have a shipper, we create an instance of (AddShip), otherwise (AddShipment) |
||
253 | * |
||
254 | * @return AddShip|AddShipment |
||
255 | */ |
||
256 | private function createShipmentObject() |
||
265 | |||
266 | /** |
||
267 | * Check if we have a shipper to attach to the shipment |
||
268 | * |
||
269 | * @return bool |
||
270 | */ |
||
271 | private function hasShipper() |
||
275 | |||
276 | /** ************************************************************************************************************** |
||
277 | * Setters and Getters |
||
278 | * **************************************************************************************************************/ |
||
279 | |||
280 | /** |
||
281 | * @return string |
||
282 | */ |
||
283 | public function getReferenceNumber(): string |
||
287 | |||
288 | /** |
||
289 | * @param string $referenceNumber |
||
290 | * |
||
291 | * @return Shipment |
||
292 | */ |
||
293 | public function setReferenceNumber(string $referenceNumber): self |
||
299 | |||
300 | /** |
||
301 | * @return string |
||
302 | */ |
||
303 | public function getType(): string |
||
307 | |||
308 | /** |
||
309 | * @param string $type |
||
310 | * |
||
311 | * @return Shipment |
||
312 | */ |
||
313 | public function setType(string $type): self |
||
319 | |||
320 | /** |
||
321 | * @return int |
||
322 | */ |
||
323 | public function getItemsCount(): int |
||
327 | |||
328 | /** |
||
329 | * @param int $itemsCount |
||
330 | * |
||
331 | * @return Shipment |
||
332 | */ |
||
333 | public function setItemsCount(int $itemsCount): self |
||
339 | |||
340 | /** |
||
341 | * @return int |
||
342 | */ |
||
343 | public function getWeight(): int |
||
347 | |||
348 | /** |
||
349 | * @param int $weight |
||
350 | * |
||
351 | * @return Shipment |
||
352 | */ |
||
353 | public function setWeight(int $weight): self |
||
359 | |||
360 | /** |
||
361 | * @return string |
||
362 | */ |
||
363 | public function getId() |
||
367 | |||
368 | /** |
||
369 | * @param string $id |
||
370 | * |
||
371 | * @return Shipment |
||
372 | */ |
||
373 | public function setId(string $id): self |
||
379 | |||
380 | /** |
||
381 | * @return string |
||
382 | */ |
||
383 | public function getDescription() |
||
387 | |||
388 | /** |
||
389 | * @param string $description |
||
390 | * |
||
391 | * @return Shipment |
||
392 | */ |
||
393 | public function setDescription(string $description): self |
||
399 | |||
400 | /** |
||
401 | * @return string |
||
402 | */ |
||
403 | public function getSentDate() |
||
407 | |||
408 | /** |
||
409 | * @param string $sentDate |
||
410 | * |
||
411 | * @return Shipment |
||
412 | */ |
||
413 | public function setSentDate(string $sentDate): self |
||
419 | |||
420 | /** |
||
421 | * @return int |
||
422 | */ |
||
423 | public function getCashOnDelivery() |
||
427 | |||
428 | /** |
||
429 | * @param int $cashOnDelivery |
||
430 | * |
||
431 | * @return Shipment |
||
432 | */ |
||
433 | public function setCashOnDelivery(int $cashOnDelivery): self |
||
439 | |||
440 | /** |
||
441 | * @return string |
||
442 | */ |
||
443 | public function getDefaultCurrency() |
||
447 | |||
448 | /** |
||
449 | * @param string $defaultCurrency |
||
450 | * |
||
451 | * @return Shipment |
||
452 | */ |
||
453 | public function setDefaultCurrency(string $defaultCurrency): self |
||
459 | |||
460 | /** |
||
461 | * @return string |
||
462 | */ |
||
463 | public function getValue() |
||
467 | |||
468 | /** |
||
469 | * @param string $value |
||
470 | * |
||
471 | * @return Shipment |
||
472 | */ |
||
473 | public function setValue(string $value): self |
||
479 | |||
480 | /** |
||
481 | * @return string |
||
482 | */ |
||
483 | public function getValueCurrency() |
||
487 | |||
488 | /** |
||
489 | * @param string $valueCurrency |
||
490 | * |
||
491 | * @return Shipment |
||
492 | */ |
||
493 | public function setValueCurrency(string $valueCurrency): self |
||
499 | |||
500 | /** |
||
501 | * @return string |
||
502 | */ |
||
503 | public function getCustoms() |
||
507 | |||
508 | /** |
||
509 | * @param string $customs |
||
510 | * |
||
511 | * @return Shipment |
||
512 | */ |
||
513 | public function setCustoms(string $customs): self |
||
519 | |||
520 | /** |
||
521 | * @return string |
||
522 | */ |
||
523 | public function getCustomsCurrency() |
||
527 | |||
528 | /** |
||
529 | * @param string $customsCurrency |
||
530 | * |
||
531 | * @return Shipment |
||
532 | */ |
||
533 | public function setCustomsCurrency(string $customsCurrency): self |
||
539 | |||
540 | /** |
||
541 | * @return string |
||
542 | */ |
||
543 | public function getInsurance() |
||
547 | |||
548 | /** |
||
549 | * @param string $insurance |
||
550 | * |
||
551 | * @return Shipment |
||
552 | */ |
||
553 | public function setInsurance(string $insurance): self |
||
559 | |||
560 | /** |
||
561 | * @return string |
||
562 | */ |
||
563 | public function getInsuranceCurrency() |
||
567 | |||
568 | /** |
||
569 | * @param string $insuranceCurrency |
||
570 | * |
||
571 | * @return Shipment |
||
572 | */ |
||
573 | public function setInsuranceCurrency(string $insuranceCurrency): self |
||
579 | |||
580 | /** |
||
581 | * @return string |
||
582 | */ |
||
583 | public function getDeliveryDate() |
||
587 | |||
588 | /** |
||
589 | * @param string $deliveryDate |
||
590 | * |
||
591 | * @return Shipment |
||
592 | */ |
||
593 | public function setDeliveryDate(string $deliveryDate): self |
||
599 | |||
600 | /** |
||
601 | * @return string |
||
602 | */ |
||
603 | public function getGpsPoints() |
||
607 | |||
608 | /** |
||
609 | * @param string $gpsPoints |
||
610 | * |
||
611 | * @return Shipment |
||
612 | */ |
||
613 | public function setGpsPoints(string $gpsPoints): self |
||
619 | |||
620 | /** |
||
621 | * @return Customer |
||
622 | */ |
||
623 | public function getCustomer(): Customer |
||
627 | |||
628 | /** |
||
629 | * @param Customer $customer |
||
630 | * |
||
631 | * @return Shipment |
||
632 | */ |
||
633 | public function setCustomer(Customer $customer): self |
||
639 | |||
640 | /** |
||
641 | * @return Shipper |
||
642 | */ |
||
643 | public function getShipper() |
||
647 | |||
648 | /** |
||
649 | * @param Shipper $shipper |
||
650 | * |
||
651 | * @return Shipment |
||
652 | */ |
||
653 | public function setShipper(Shipper $shipper): self |
||
659 | } |
||
660 |
It seems like the method you are trying to call exists only in some of the possible types.
Let’s take a look at an example:
Available Fixes
Add an additional type-check:
Only allow a single type to be passed if the variable comes from a parameter: