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 |
||
33 | class FeatureContext implements Context |
||
34 | { |
||
35 | protected $engine; |
||
36 | |||
37 | /** @var Customer */ |
||
38 | protected $customer; |
||
39 | /** |
||
40 | * @var \hiqdev\php\billing\price\PriceInterface|\hiqdev\php\billing\charge\FormulaChargeModifierTrait |
||
41 | * |
||
42 | * TODO: FormulaChargeModifierTrait::setFormula() must be moved to interface |
||
43 | */ |
||
44 | protected $price; |
||
45 | |||
46 | /** @var string */ |
||
47 | protected $formula; |
||
48 | |||
49 | /** |
||
50 | * @var \hiqdev\php\billing\action\ActionInterface|\hiqdev\php\billing\action\AbstractAction |
||
51 | */ |
||
52 | protected $action; |
||
53 | /** |
||
54 | * @var ChargeInterface[] |
||
55 | */ |
||
56 | protected $charges; |
||
57 | |||
58 | /** @var \Money\MoneyParser */ |
||
59 | protected $moneyParser; |
||
60 | |||
61 | /** @var string */ |
||
62 | protected $expectedError; |
||
63 | |||
64 | /** |
||
65 | * Initializes context. |
||
66 | */ |
||
67 | public function __construct() |
||
72 | |||
73 | /** |
||
74 | * @Given /(\S+) (\S+) price is ([0-9.]+) (\w+) per (\w+)/ |
||
75 | */ |
||
76 | View Code Duplication | public function priceIs($target, $type, $sum, $currency, $unit) |
|
|
|||
77 | { |
||
78 | $type = new Type(Type::ANY, $type); |
||
79 | $target = new Target(Target::ANY, $target); |
||
80 | $quantity = Quantity::create($unit, 0); |
||
81 | $sum = $this->moneyParser->parse($sum, $currency); |
||
82 | $this->price = new SinglePrice(null, $type, $target, null, $quantity, $sum); |
||
83 | } |
||
84 | |||
85 | /** |
||
86 | * @Given /action is (\S+) (\w+) ([0-9.]+) (\S+)/ |
||
87 | */ |
||
88 | View Code Duplication | public function actionIs($target, $type, $amount, $unit) |
|
89 | { |
||
90 | $type = new Type(Type::ANY, $type); |
||
91 | $target = new Target(Target::ANY, $target); |
||
92 | $quantity = Quantity::create($unit, $amount); |
||
93 | $time = new DateTimeImmutable(); |
||
94 | $this->action = new Action(null, $type, $target, $quantity, $this->customer, $time); |
||
95 | } |
||
96 | |||
97 | /** |
||
98 | * @Given /formula is (.+)/ |
||
99 | * @param string $formula |
||
100 | */ |
||
101 | public function formulaIs(string $formula): void |
||
105 | |||
106 | /** |
||
107 | * @Given /formula continues (.+)/ |
||
108 | * @param string $formula |
||
109 | */ |
||
110 | public function formulaContinues(string $formula): void |
||
114 | |||
115 | protected function getFormulaEngine() |
||
123 | |||
124 | /** |
||
125 | * @When /action date is ([0-9.-]+)/ |
||
126 | * @param string $date |
||
127 | * @throws \Exception |
||
128 | */ |
||
129 | public function actionDateIs(string $date): void |
||
133 | |||
134 | /** |
||
135 | * @Then /^error is$/m |
||
136 | */ |
||
137 | public function multilineErrorIs(\Behat\Gherkin\Node\PyStringNode $value) |
||
141 | |||
142 | /** |
||
143 | * @Then /^error is (.+)$/ |
||
144 | * |
||
145 | * @param string $error |
||
146 | */ |
||
147 | public function errorIs($error): void |
||
151 | |||
152 | /** |
||
153 | * @Then /^(\w+) charge is ?$/ |
||
154 | * @param string $numeral |
||
155 | */ |
||
156 | public function emptyCharge(string $numeral): void |
||
160 | |||
161 | /** |
||
162 | * @Then /^(\w+) charge is (\S+) +([0-9.]+) ([A-Z]{3})$/ |
||
163 | */ |
||
164 | public function chargeWithSum($numeral, $type = null, $sum = null, $currency = null): void |
||
168 | |||
169 | /** |
||
170 | * @Then /^(\w+) charge is (\S+) +([0-9.]+) ([A-Z]{3}) reason (.+)/ |
||
171 | */ |
||
172 | public function chargeWithReason($numeral, $type = null, $sum = null, $currency = null, $reason = null): void |
||
176 | |||
177 | public function chargeIs($numeral, $type = null, $sum = null, $currency = null, $reason = null): void |
||
185 | |||
186 | /** |
||
187 | * @When /^calculating charges$/ |
||
188 | */ |
||
189 | public function calculateCharges(): void |
||
196 | |||
197 | public function expectError(Closure $closure): void |
||
212 | |||
213 | protected function isExpectedError(\Exception $e): bool |
||
217 | |||
218 | protected function startsWith(string $string, string $prefix = null): bool |
||
222 | |||
223 | /** |
||
224 | * @param ChargeInterface|null $charge |
||
225 | * @param string|null $type |
||
226 | * @param string|null $sum |
||
227 | * @param string|null $currency |
||
228 | * @param string|null $reason |
||
229 | */ |
||
230 | public function assertCharge($charge, $type, $sum, $currency, $reason): void |
||
245 | |||
246 | private function ensureNo(string $numeral): int |
||
256 | } |
||
257 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.