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:
Complex classes like DisplayTabbed 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 DisplayTabbed, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
18 | class DisplayTabbed implements DisplayInterface, FormInterface |
||
19 | { |
||
20 | use FormElements, VisibleCondition, \SleepingOwl\Admin\Traits\Renderable; |
||
21 | |||
22 | /** |
||
23 | * @var string |
||
24 | */ |
||
25 | protected $view = 'display.tabbed'; |
||
26 | |||
27 | /** |
||
28 | * DisplayTabbed constructor. |
||
29 | * |
||
30 | * @param Closure|TabInterface[] $tabs |
||
31 | */ |
||
32 | public function __construct($tabs = null) |
||
40 | |||
41 | /** |
||
42 | * Initialize tabbed interface. |
||
43 | */ |
||
44 | public function initialize() |
||
78 | |||
79 | /** |
||
80 | * @return Model $model|null |
||
81 | */ |
||
82 | public function getModel() |
||
90 | |||
91 | /** |
||
92 | * @param string $class |
||
93 | * |
||
94 | * @return $this |
||
95 | */ |
||
96 | public function setModelClass($class) |
||
106 | |||
107 | /** |
||
108 | * @return TabInterface[]|DisplayTabsCollection |
||
109 | */ |
||
110 | public function getTabs() |
||
114 | |||
115 | /** |
||
116 | * @param Closure|TabInterface[] $tabs |
||
117 | * |
||
118 | * @return $this |
||
119 | */ |
||
120 | public function setTabs($tabs) |
||
128 | |||
129 | /** |
||
130 | * @param array $elements |
||
131 | * |
||
132 | * @return $this |
||
133 | */ |
||
134 | public function setElements(array $elements) |
||
146 | |||
147 | /** |
||
148 | * @param Renderable $display |
||
149 | * @param string $label |
||
150 | * @param bool|false $active |
||
151 | * |
||
152 | * @return TabInterface |
||
153 | */ |
||
154 | public function appendTab(Renderable $display, $label, $active = false) |
||
162 | |||
163 | /** |
||
164 | * @param TabInterface $element |
||
165 | * |
||
166 | * @return $this |
||
167 | */ |
||
168 | public function addElement(TabInterface $element) |
||
174 | |||
175 | /** |
||
176 | * @param string $action |
||
177 | * |
||
178 | * @return $this |
||
179 | */ |
||
180 | public function setAction($action) |
||
190 | |||
191 | /** |
||
192 | * @param int $id |
||
193 | * |
||
194 | * @return $this |
||
195 | */ |
||
196 | public function setId($id) |
||
206 | |||
207 | /** |
||
208 | * @param \Illuminate\Http\Request $request |
||
209 | * @param ModelConfigurationInterface $model |
||
210 | * |
||
211 | * @return void |
||
212 | */ |
||
213 | View Code Duplication | public function validateForm(\Illuminate\Http\Request $request, ModelConfigurationInterface $model = null) |
|
223 | |||
224 | /** |
||
225 | * @param \Illuminate\Http\Request $request |
||
226 | * @param ModelConfigurationInterface $model |
||
227 | * |
||
228 | * @return void |
||
229 | */ |
||
230 | View Code Duplication | public function saveForm(\Illuminate\Http\Request $request, ModelConfigurationInterface $model = null) |
|
240 | |||
241 | /** |
||
242 | * @return null |
||
243 | */ |
||
244 | public function getValue() |
||
247 | |||
248 | /** |
||
249 | * @return bool |
||
250 | */ |
||
251 | public function isReadonly() |
||
255 | |||
256 | /** |
||
257 | * @return bool |
||
258 | */ |
||
259 | public function isValueSkipped() |
||
263 | |||
264 | /** |
||
265 | * @return array |
||
266 | */ |
||
267 | public function toArray() |
||
273 | |||
274 | /** |
||
275 | * Using in trait FormElements;. |
||
276 | * |
||
277 | * @param $object |
||
278 | * |
||
279 | * @return mixed |
||
280 | */ |
||
281 | protected function getElementContainer($object) |
||
285 | } |
||
286 |
PHP has two types of connecting operators (logical operators, and boolean operators):
and
&&
or
||
The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like
&&
, or||
.Let’s take a look at a few examples:
Logical Operators are used for Control-Flow
One case where you explicitly want to use logical operators is for control-flow such as this:
Since
die
introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined withthrow
at this point:These limitations lead to logical operators rarely being of use in current PHP code.