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 |
||
23 | class Expression implements ArrayableInterface |
||
24 | { |
||
25 | private $expression = array(); |
||
26 | |||
27 | /** |
||
28 | * Returns true only when all its expressions evaluate to true. |
||
29 | * Accepts any number of argument expressions. |
||
30 | * |
||
31 | * @link http://docs.mongodb.org/manual/reference/operator/aggregation/and |
||
32 | */ |
||
33 | public function all() |
||
34 | { |
||
35 | $expressions = func_get_args(); |
||
36 | |||
37 | $this->expression['$and'] = self::normalizeEach($expressions); |
||
38 | |||
39 | return $this; |
||
40 | } |
||
41 | |||
42 | /** |
||
43 | * Returns the boolean value that is the opposite of its argument expression. |
||
44 | * Accepts a single argument expression. |
||
45 | * |
||
46 | * @link http://docs.mongodb.org/manual/reference/operator/aggregation/not |
||
47 | */ |
||
48 | public function not($expression) |
||
49 | { |
||
50 | $this->expression['$not'] = self::normalize($expression); |
||
51 | return $this; |
||
52 | } |
||
53 | |||
54 | /** |
||
55 | * Returns true when any of its expressions evaluates to true. |
||
56 | * Accepts any number of argument expressions. |
||
57 | * |
||
58 | * @link http://docs.mongodb.org/manual/reference/operator/aggregation/or |
||
59 | */ |
||
60 | public function any() |
||
61 | { |
||
62 | $expressions = func_get_args(); |
||
63 | |||
64 | $this->expression['$or'] = self::normalizeEach($expressions); |
||
65 | |||
66 | return $this; |
||
67 | } |
||
68 | |||
69 | /** |
||
70 | * @kibk http://docs.mongodb.org/manual/reference/operator/aggregation/add/ |
||
71 | * @param array<literal|callable|\Sokil\Mongo\Pipeline\Expression> $expressions may me specified as one array of expressions and as list of expressions |
||
72 | */ |
||
73 | View Code Duplication | public function add($expressions) |
|
|
|||
74 | { |
||
75 | if (func_num_args() > 1) { |
||
76 | $expressions = func_get_args(); |
||
77 | } |
||
78 | |||
79 | $this->expression['$add'] = self::normalizeEach($expressions); |
||
80 | |||
81 | return $this; |
||
82 | } |
||
83 | |||
84 | /** |
||
85 | * @link http://docs.mongodb.org/manual/reference/operator/aggregation/divide/ |
||
86 | * @param literal|callable|\Sokil\Mongo\Pipeline\Expression $expression1 |
||
87 | * @param literal|callable|\Sokil\Mongo\Pipeline\Expression $expression2 |
||
88 | */ |
||
89 | public function divide($expression1, $expression2) |
||
90 | { |
||
91 | $this->expression['$divide'] = self::normalizeEach(array( |
||
92 | $expression1, |
||
93 | $expression2 |
||
94 | )); |
||
95 | |||
96 | return $this; |
||
97 | } |
||
98 | |||
99 | /** |
||
100 | * @link http://docs.mongodb.org/manual/reference/operator/aggregation/mod/ |
||
101 | * @param literal|callable|\Sokil\Mongo\Pipeline\Expression $expression1 |
||
102 | * @param literal|callable|\Sokil\Mongo\Pipeline\Expression $expression2 |
||
103 | */ |
||
104 | public function mod($expression1, $expression2) |
||
105 | { |
||
106 | $this->expression['$mod'] = self::normalizeEach(array( |
||
107 | $expression1, |
||
108 | $expression2 |
||
109 | )); |
||
110 | |||
111 | return $this; |
||
112 | } |
||
113 | |||
114 | /** |
||
115 | * @link http://docs.mongodb.org/manual/reference/operator/aggregation/multiply/ |
||
116 | * @param array<literal|callable|\Sokil\Mongo\Pipeline\Expression> $expressions may me specified as one array of expressions and as list of expressions |
||
117 | */ |
||
118 | View Code Duplication | public function multiply($expressions) |
|
119 | { |
||
120 | if (func_num_args() > 1) { |
||
121 | $expressions = func_get_args(); |
||
122 | } |
||
123 | |||
124 | $this->expression['$multiply'] = self::normalizeEach($expressions); |
||
125 | |||
126 | return $this; |
||
127 | } |
||
128 | |||
129 | /** |
||
130 | * @link http://docs.mongodb.org/manual/reference/operator/aggregation/subtract/ |
||
131 | * @param literal|callable|\Sokil\Mongo\Pipeline\Expression $expression1 |
||
132 | * @param literal|callable|\Sokil\Mongo\Pipeline\Expression $expression2 |
||
133 | */ |
||
134 | public function subtract($expression1, $expression2) |
||
135 | { |
||
136 | $this->expression['$subtract'] = self::normalizeEach(array( |
||
137 | $expression1, |
||
138 | $expression2 |
||
139 | )); |
||
140 | |||
141 | return $this; |
||
142 | } |
||
143 | |||
144 | /** |
||
145 | * Convert expressions specified in different formats to canonical form |
||
146 | * |
||
147 | * @param array<callable|\Sokil\Mongo\Expression> $expressions |
||
148 | */ |
||
149 | public static function normalizeEach(array $expressions) |
||
150 | { |
||
151 | foreach ($expressions as $i => $expression) { |
||
152 | $expressions[$i] = self::normalize($expression); |
||
153 | } |
||
154 | |||
155 | return $expressions; |
||
156 | } |
||
157 | |||
158 | /** |
||
159 | * Convert expression specified in different formats to canonical form |
||
160 | * |
||
161 | * @param Expression|callable $expression |
||
162 | * @return array |
||
163 | */ |
||
164 | public static function normalize($expression) |
||
165 | { |
||
166 | if (is_callable($expression)) { |
||
167 | $expressionConfigurator = $expression; |
||
168 | $expression = new Expression; |
||
169 | call_user_func($expressionConfigurator, $expression); |
||
170 | } |
||
171 | |||
172 | if ($expression instanceof Expression) { |
||
173 | $expression = $expression->toArray(); |
||
174 | } elseif (is_array($expression)) { |
||
175 | foreach ($expression as $fieldName => $value) { |
||
176 | $expression[$fieldName] = self::normalize($value); |
||
177 | } |
||
178 | } |
||
179 | |||
180 | return $expression; |
||
181 | } |
||
182 | |||
183 | public function toArray() |
||
187 | } |
||
188 |
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.