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 DocumentManager 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 DocumentManager, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
15 | class DocumentManager implements ObjectManager |
||
16 | { |
||
17 | /** |
||
18 | * @var Configuration |
||
19 | */ |
||
20 | private $config; |
||
21 | |||
22 | /** |
||
23 | * @var Mapping\ClassMetadataFactory |
||
24 | */ |
||
25 | private $metadataFactory; |
||
26 | |||
27 | /** |
||
28 | * @var UnitOfWork |
||
29 | */ |
||
30 | private $unitOfWork = null; |
||
31 | |||
32 | /** |
||
33 | * @var \Doctrine\ODM\CouchDB\Proxy\ProxyFactory |
||
34 | */ |
||
35 | private $proxyFactory = null; |
||
36 | |||
37 | /** |
||
38 | * @var array |
||
39 | */ |
||
40 | private $repositories = array(); |
||
41 | |||
42 | /** |
||
43 | * @var CouchDBClient |
||
44 | */ |
||
45 | private $couchDBClient = null; |
||
46 | |||
47 | /** |
||
48 | * @var EventManager |
||
49 | */ |
||
50 | private $evm; |
||
51 | |||
52 | /** |
||
53 | * @param CouchDBClient $couchClient |
||
54 | * @param Configuration $config |
||
55 | * @param EventManager $evm |
||
56 | */ |
||
57 | public function __construct(CouchDBClient $couchClient, Configuration $config = null, EventManager $evm = null) |
||
66 | |||
67 | /** |
||
68 | * @return EventManager |
||
69 | */ |
||
70 | public function getEventManager() |
||
74 | |||
75 | /** |
||
76 | * @return CouchDBClient |
||
77 | */ |
||
78 | public function getCouchDBClient() |
||
82 | |||
83 | /** |
||
84 | * Factory method for a Document Manager. |
||
85 | * |
||
86 | * @param array|CouchDBClient $couchParams |
||
87 | * @param Configuration $config |
||
88 | * @param EventManager $evm |
||
89 | * @return DocumentManager |
||
90 | * @throws \InvalidArgumentException |
||
91 | */ |
||
92 | public static function create($couchParams, Configuration $config = null, EventManager $evm = null) |
||
104 | |||
105 | /** |
||
106 | * @return ClassMetadataFactory |
||
107 | */ |
||
108 | public function getMetadataFactory() |
||
112 | |||
113 | /** |
||
114 | * @return Proxy\ProxyFactory |
||
115 | */ |
||
116 | public function getProxyFactory() |
||
120 | |||
121 | public function getHttpClient() |
||
125 | |||
126 | public function getDatabase() |
||
130 | |||
131 | /** |
||
132 | * @return Configuration |
||
133 | */ |
||
134 | public function getConfiguration() |
||
138 | |||
139 | /** |
||
140 | * @return ClassMetadataFactory |
||
141 | */ |
||
142 | public function getClassMetadataFactory() |
||
146 | |||
147 | /** |
||
148 | * @param string $class |
||
149 | * @return \Doctrine\ODM\CouchDB\Mapping\ClassMetadata |
||
150 | */ |
||
151 | public function getClassMetadata($class) |
||
155 | |||
156 | /** |
||
157 | * Find the Document with the given id. |
||
158 | * |
||
159 | * Will return null if the document wasn't found. |
||
160 | * |
||
161 | * @param string $documentName |
||
162 | * @param string $id |
||
163 | * @return object |
||
164 | */ |
||
165 | public function find($documentName, $id) |
||
169 | |||
170 | /** |
||
171 | * @param string $documentName |
||
172 | * @return \Doctrine\ODM\CouchDB\DocumentRepository |
||
173 | */ |
||
174 | public function getRepository($documentName) |
||
188 | |||
189 | /** |
||
190 | * Create a Query for the view in the specified design document. |
||
191 | * |
||
192 | * @param string $designDocName |
||
193 | * @param string $viewName |
||
194 | * @return \Doctrine\ODM\CouchDB\View\ODMQuery |
||
195 | */ |
||
196 | View Code Duplication | public function createQuery($designDocName, $viewName) |
|
206 | |||
207 | /** |
||
208 | * Create a Native query for the view of the specified design document. |
||
209 | * |
||
210 | * A native query will return an array of data from the &include_docs=true parameter. |
||
211 | * |
||
212 | * @param string $designDocName |
||
213 | * @param string $viewName |
||
214 | * @return \Doctrine\CouchDB\View\Query |
||
215 | */ |
||
216 | View Code Duplication | public function createNativeQuery($designDocName, $viewName) |
|
225 | |||
226 | /** |
||
227 | * Create a CouchDB-Lucene Query. |
||
228 | * |
||
229 | * @param string $designDocName |
||
230 | * @param string $viewName |
||
231 | * @return \Doctrine\ODM\CouchDB\View\ODMLuceneQuery |
||
232 | */ |
||
233 | View Code Duplication | public function createLuceneQuery($designDocName, $viewName) |
|
247 | |||
248 | public function persist($object) |
||
252 | |||
253 | public function remove($object) |
||
257 | |||
258 | /** |
||
259 | * Refresh the given document by querying the CouchDB to get the current state. |
||
260 | * |
||
261 | * @param object $document |
||
262 | */ |
||
263 | public function refresh($document) |
||
267 | |||
268 | public function merge($document) |
||
272 | |||
273 | public function detach($document) |
||
277 | |||
278 | /** |
||
279 | * Gets a reference to the entity identified by the given type and identifier |
||
280 | * without actually loading it, if the entity is not yet loaded. |
||
281 | * |
||
282 | * @param string $documentName The name of the entity type. |
||
283 | * @param mixed $identifier The entity identifier. |
||
284 | * @return object The entity reference. |
||
285 | */ |
||
286 | public function getReference($documentName, $identifier) |
||
299 | |||
300 | public function flush() |
||
304 | |||
305 | /** |
||
306 | * @param object $document |
||
307 | * @return bool |
||
308 | */ |
||
309 | public function contains($document) |
||
313 | |||
314 | /** |
||
315 | * @return UnitOfWork |
||
316 | */ |
||
317 | public function getUnitOfWork() |
||
321 | |||
322 | /** |
||
323 | * Clears the ObjectManager. All objects that are currently managed |
||
324 | * by this ObjectManager become detached. |
||
325 | * |
||
326 | * @param string $objectName if given, only objects of this type will get detached |
||
327 | * @throws CouchDBException |
||
328 | */ |
||
329 | public function clear($objectName = null) |
||
339 | |||
340 | /** |
||
341 | * Initialize an object that is a lazy load proxy, or do nothing. |
||
342 | * |
||
343 | * @param object $obj |
||
344 | */ |
||
345 | public function initializeObject($obj) |
||
353 | } |
||
354 |
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.