Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
1 | <?php namespace SimpleUPS\Track\SmallPackage; |
||
14 | class Shipment extends \SimpleUPS\Shipment |
||
15 | { |
||
16 | |||
17 | private |
||
18 | /* @var \SimpleUPS\Track\Status $status */ |
||
19 | $status, |
||
20 | /* @var \SimpleUPS\Track\ShipmentType $shipmentType */ |
||
21 | $shipmentType, |
||
22 | |||
23 | /* @var ReferenceNumber $referenceNumber */ |
||
24 | $referenceNumber, |
||
25 | /* @var string $shipmentIdentificationNumber */ |
||
26 | $shipmentIdentificationNumber, |
||
27 | |||
28 | /* @var \DateTime $pickupDate */ |
||
29 | $pickupDate, |
||
30 | /* @var Weight $weight */ |
||
31 | $weight, |
||
32 | |||
33 | /* @var \DateTime $deliveryTime */ |
||
34 | $deliveryTime; |
||
35 | |||
36 | /** |
||
37 | * @internal |
||
38 | * |
||
39 | * @param \DateTime $deliveryTime |
||
40 | * |
||
41 | * @return Shipment |
||
42 | */ |
||
43 | public function setDeliveryTime(\DateTime $deliveryTime) |
||
48 | |||
49 | /** |
||
50 | * When the item was delivered |
||
51 | * @see getStatus() |
||
52 | * @return \DateTime |
||
53 | */ |
||
54 | public function getDeliveryTime() |
||
58 | |||
59 | /** |
||
60 | * @internal |
||
61 | * |
||
62 | * @param \DateTime $pickupDate |
||
63 | * |
||
64 | * @return Shipment |
||
65 | */ |
||
66 | public function setPickupDate(\DateTime $pickupDate) |
||
71 | |||
72 | /** |
||
73 | * Date the shipment was picked up from the shipper |
||
74 | * @return \DateTime |
||
75 | */ |
||
76 | public function getPickupDate() |
||
80 | |||
81 | /** |
||
82 | * @internal |
||
83 | * |
||
84 | * @param \SimpleUPS\Track\ShipmentType $shipmentType |
||
85 | * |
||
86 | * @return Shipment |
||
87 | */ |
||
88 | public function setShipmentType(\SimpleUPS\Track\ShipmentType $shipmentType) |
||
93 | |||
94 | /** |
||
95 | * The type of shipment being tracked |
||
96 | * @return string |
||
97 | */ |
||
98 | public function getShipmentType() |
||
102 | |||
103 | /** |
||
104 | * Determine if this shipment is a small package |
||
105 | * @return bool |
||
106 | */ |
||
107 | public function isSmallPackage() |
||
111 | |||
112 | /** |
||
113 | * Determine if this shipment is freight |
||
114 | * @return bool |
||
115 | */ |
||
116 | public function isFreight() |
||
120 | |||
121 | /** |
||
122 | * Determine if this shipment is mail innovations |
||
123 | * @return bool |
||
124 | */ |
||
125 | public function isMailInnovation() |
||
129 | |||
130 | /** |
||
131 | * @internal |
||
132 | * |
||
133 | * @param Status $status |
||
134 | * |
||
135 | * @return Shipment |
||
136 | */ |
||
137 | public function setStatus(Status $status) |
||
142 | |||
143 | /** |
||
144 | * Status of shipment |
||
145 | * @return Status |
||
146 | */ |
||
147 | public function getStatus() |
||
151 | |||
152 | /** |
||
153 | * @internal |
||
154 | * |
||
155 | * @param \SimpleUPS\Weight $weight |
||
156 | * |
||
157 | * @return Shipment |
||
158 | */ |
||
159 | public function setWeight(\SimpleUPS\Weight $weight) |
||
164 | |||
165 | /** |
||
166 | * Shipment weight |
||
167 | * @return \SimpleUPS\Weight |
||
168 | */ |
||
169 | public function getWeight() |
||
173 | |||
174 | /** |
||
175 | * @internal |
||
176 | * |
||
177 | * @param ReferenceNumber $referenceNumber |
||
178 | * |
||
179 | * @return Shipment |
||
180 | */ |
||
181 | public function setReferenceNumber(ReferenceNumber $referenceNumber) |
||
186 | |||
187 | /** |
||
188 | * Shipment reference number |
||
189 | * @return ReferenceNumber |
||
190 | */ |
||
191 | public function getReferenceNumber() |
||
195 | |||
196 | /** |
||
197 | * @internal |
||
198 | * |
||
199 | * @param string $shipmentIdentificationNumber |
||
200 | * |
||
201 | * @return Shipment |
||
202 | */ |
||
203 | public function setShipmentIdentificationNumber($shipmentIdentificationNumber) |
||
208 | |||
209 | /** |
||
210 | * Shipment identification number |
||
211 | * @return string |
||
212 | */ |
||
213 | public function getShipmentIdentificationNumber() |
||
217 | |||
218 | /** |
||
219 | * @internal |
||
220 | * |
||
221 | * @param \SimpleXMLElement $xml |
||
222 | * |
||
223 | * @return Shipment |
||
224 | */ |
||
225 | public static function fromXml(\SimpleXMLElement $xml) |
||
281 | |||
282 | } |
Let’s assume that you have a directory layout like this:
and let’s assume the following content of
Bar.php
:If both files
OtherDir/Foo.php
andSomeDir/Foo.php
are loaded in the same runtime, you will see a PHP error such as the following:PHP Fatal error: Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php
However, as
OtherDir/Foo.php
does not necessarily have to be loaded and the error is only triggered if it is loaded beforeOtherDir/Bar.php
, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias: