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: