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 |
||
31 | class OrganizationContext implements Context |
||
32 | { |
||
33 | use CommonContextTrait; |
||
34 | |||
35 | /** |
||
36 | * @var JobContext |
||
37 | */ |
||
38 | private $jobContext; |
||
39 | |||
40 | /** |
||
41 | * @BeforeScenario |
||
42 | * |
||
43 | * @param BeforeScenarioScope $scope |
||
44 | */ |
||
45 | public function setupContext(BeforeScenarioScope $scope) |
||
49 | |||
50 | /** |
||
51 | * @Given I go to my organization page |
||
52 | */ |
||
53 | public function iGoToMyOrganizationPage() |
||
58 | |||
59 | /** |
||
60 | * @When I hover over name form |
||
61 | */ |
||
62 | public function iMouseOverOrganizationNameForm() |
||
67 | |||
68 | /** |
||
69 | * @Given I go to create new organization page |
||
70 | */ |
||
71 | public function iGoToCreateNewOrganizationPage() |
||
77 | |||
78 | /** |
||
79 | * @Given I go to organization overview page |
||
80 | */ |
||
81 | public function iGoToOrganizationOverviewPage() |
||
87 | |||
88 | /** |
||
89 | * @Given I want to see list organization profiles |
||
90 | */ |
||
91 | public function iWantToSeeListOrganizationProfiles() |
||
96 | |||
97 | /** |
||
98 | * @Given I have organization :name |
||
99 | * |
||
100 | * @internal param string $name |
||
101 | * @internal param TableNode|null $table |
||
102 | */ |
||
103 | public function iHaveOrganization($name) |
||
127 | |||
128 | /** |
||
129 | * @Given organization :name have jobs: |
||
130 | */ |
||
131 | public function organizationHavePublishedJob($name,TableNode $table) |
||
146 | |||
147 | /** |
||
148 | * @Given profile setting for :name is :setting |
||
149 | * @param $name |
||
150 | * @param $setting |
||
151 | */ |
||
152 | public function profileSetting($name,$setting) |
||
161 | |||
162 | /** |
||
163 | * @Given I define contact for :organization organization with: |
||
164 | * @param TableNode $table |
||
165 | */ |
||
166 | public function iDefineContactWith($name, TableNode $table) |
||
182 | |||
183 | /** |
||
184 | * @Given I go to profile page for organization :name |
||
185 | * @Given I go to profile page for my organization |
||
186 | * @param string $name |
||
187 | * @throws FailedExpectationException |
||
188 | */ |
||
189 | public function iGoToOrganizationProfilePage($name=null) |
||
202 | |||
203 | /** |
||
204 | * @param string $name |
||
205 | * @return Organization |
||
206 | * @throws FailedExpectationException |
||
207 | */ |
||
208 | public function findOrganizationByName($name, $throwException = true) |
||
221 | |||
222 | /** |
||
223 | * @Given organization :name have no job |
||
224 | * |
||
225 | * @param string $name |
||
226 | */ |
||
227 | public function organizationHaveNoJob($name) |
||
239 | |||
240 | /** |
||
241 | * @Given I want to edit my organization |
||
242 | */ |
||
243 | public function iWantToEditMyOrganization() |
||
250 | |||
251 | /** |
||
252 | * @Given I attach logo from file :file |
||
253 | * @param $file |
||
254 | */ |
||
255 | public function iAttachLogoFromFile($file) |
||
260 | |||
261 | /** |
||
262 | * @Given I remove logo from organization |
||
263 | */ |
||
264 | public function iRemoveLogoFromOrganization() |
||
270 | } |
||
271 |
Let’s take a look at an example:
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.
Available Fixes
Change the type-hint for the parameter:
Add an additional type-check:
Add the method to the interface: