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 Model 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 Model, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
8 | class Model |
||
9 | { |
||
10 | /** cache for Vocabulary objects */ |
||
11 | private $allVocabularies = null; |
||
12 | /** cache for Vocabulary objects */ |
||
13 | private $vocabsByGraph = null; |
||
14 | /** cache for Vocabulary objects */ |
||
15 | private $vocabsByUriSpace = null; |
||
16 | /** how long to store retrieved URI information in APC cache */ |
||
17 | const URI_FETCH_TTL = 86400; // 1 day |
||
18 | private $globalConfig; |
||
19 | private $logger; |
||
20 | private $resolver; |
||
21 | |||
22 | /** |
||
23 | * Initializes the Model object |
||
24 | */ |
||
25 | public function __construct($config) |
||
31 | |||
32 | /** |
||
33 | * Returns the GlobalConfig object given to the Model as a constructor parameter. |
||
34 | * @return GlobalConfig |
||
35 | */ |
||
36 | public function getConfig() { |
||
39 | |||
40 | /** |
||
41 | * Configures the logging facility |
||
42 | */ |
||
43 | private function initializeLogging() { |
||
63 | |||
64 | /** |
||
65 | * Return the logging facility |
||
66 | * @return object logger |
||
67 | */ |
||
68 | public function getLogger() { |
||
71 | |||
72 | /** |
||
73 | * Return the version of this Skosmos installation, or "unknown" if |
||
74 | * it cannot be determined. The version information is based on Git tags. |
||
75 | * @return string version |
||
76 | */ |
||
77 | public function getVersion() |
||
90 | |||
91 | /** |
||
92 | * Return all the vocabularies available. |
||
93 | * @param boolean $categories whether you want everything included in a subarray of |
||
94 | * a category. |
||
95 | * @param boolean $shortname set to true if you want the vocabularies sorted by |
||
96 | * their shortnames instead of ther titles. |
||
97 | */ |
||
98 | public function getVocabularyList($categories = true, $shortname = false) |
||
126 | |||
127 | /** |
||
128 | * Return all types (RDFS/OWL classes) present in the specified vocabulary or all vocabularies. |
||
129 | * @return array Array with URIs (string) as key and array of (label, superclassURI) as value |
||
130 | */ |
||
131 | public function getTypes($vocid = null, $lang = null) |
||
150 | |||
151 | /** |
||
152 | * Return the languages present in the configured vocabularies. |
||
153 | * @return array Array with lang codes (string) |
||
154 | */ |
||
155 | public function getLanguages($lang) |
||
168 | |||
169 | /** |
||
170 | * returns a concept's RDF data in downloadable format |
||
171 | * @param string $vocid vocabulary id, or null for global data (from all vocabularies) |
||
172 | * @param string $uri concept URI |
||
173 | * @param string $format the format in which you want to get the result, currently this function supports |
||
174 | * text/turtle, application/rdf+xml and application/json |
||
175 | * @return string RDF data in the requested serialization |
||
176 | */ |
||
177 | public function getRDF($vocid, $uri, $format) |
||
208 | |||
209 | /** |
||
210 | * Makes a SPARQL-query to the endpoint that retrieves concept |
||
211 | * references as it's search results. |
||
212 | * @param ConceptSearchParameters $params an object that contains all the parameters needed for the search |
||
213 | * @return array search results |
||
214 | */ |
||
215 | public function searchConcepts($params) |
||
272 | |||
273 | /** |
||
274 | * Function for performing a search for concepts and their data fields. |
||
275 | * @param ConceptSearchParameters $params an object that contains all the parameters needed for the search |
||
276 | * @return array array with keys 'count' and 'results' |
||
277 | */ |
||
278 | public function searchConceptsAndInfo($params) |
||
328 | |||
329 | /** |
||
330 | * Creates dataobjects from an input array. |
||
331 | * @param string $class the type of class eg. 'Vocabulary'. |
||
332 | * @param array $resarr contains the EasyRdf\Resources. |
||
333 | */ |
||
334 | private function createDataObjects($class, $resarr) |
||
343 | |||
344 | /** |
||
345 | * Returns the cached vocabularies. |
||
346 | * @return array of Vocabulary dataobjects |
||
347 | */ |
||
348 | public function getVocabularies() |
||
370 | |||
371 | /** |
||
372 | * Returns the cached vocabularies from a category. |
||
373 | * @param EasyRdf\Resource $cat the category in question |
||
374 | * @return array of vocabulary dataobjects |
||
375 | */ |
||
376 | public function getVocabulariesInCategory($cat) |
||
381 | |||
382 | /** |
||
383 | * Creates dataobjects of all the different vocabulary categories (Health etc.). |
||
384 | * @return array of Dataobjects of the type VocabularyCategory. |
||
385 | */ |
||
386 | public function getVocabularyCategories() |
||
395 | |||
396 | /** |
||
397 | * Returns the label defined in config.ttl with the appropriate language. |
||
398 | * @param string $lang language code of returned labels, eg. 'fi' |
||
399 | * @return string the label for vocabulary categories. |
||
400 | */ |
||
401 | public function getClassificationLabel($lang) |
||
408 | |||
409 | /** |
||
410 | * Returns a single cached vocabulary. |
||
411 | * @param string $vocid the vocabulary id eg. 'mesh'. |
||
412 | * @return Vocabulary dataobject |
||
413 | */ |
||
414 | public function getVocabulary($vocid): Vocabulary |
||
424 | |||
425 | /** |
||
426 | * Return the vocabulary that is stored in the given graph on the given endpoint. |
||
427 | * |
||
428 | * @param $graph string graph URI |
||
429 | * @param $endpoint string endpoint URL (default SPARQL endpoint if omitted) |
||
430 | * @return Vocabulary vocabulary of this URI, or null if not found |
||
431 | */ |
||
432 | public function getVocabularyByGraph($graph, $endpoint = null) |
||
453 | |||
454 | /** |
||
455 | * When multiple vocabularies share same URI namespace, return the |
||
456 | * vocabulary in which the URI is actually defined (has a label). |
||
457 | * |
||
458 | * @param Vocabulary[] $vocabs vocabularies to search |
||
459 | * @param string $uri URI to look for |
||
460 | * @param $preferredVocabId string ID of the preferred vocabulary to return if more than one is found |
||
461 | * @return Vocabulary the vocabulary with the URI |
||
462 | */ |
||
463 | |||
464 | private function disambiguateVocabulary($vocabs, $uri, $preferredVocabId = null) |
||
495 | |||
496 | /** |
||
497 | * Guess which vocabulary a URI originates from, based on the declared |
||
498 | * vocabulary URI spaces. |
||
499 | * |
||
500 | * @param $uri string URI to search |
||
501 | * @param $preferredVocabId string ID of the preferred vocabulary to return if more than one is found |
||
502 | * @return Vocabulary vocabulary of this URI, or null if not found |
||
503 | */ |
||
504 | public function guessVocabularyFromURI($uri, $preferredVocabId = null) |
||
531 | |||
532 | /** |
||
533 | * Get the label for a resource, preferring 1. the given language 2. configured languages 3. any language. |
||
534 | * @param EasyRdf\Resource $res resource whose label to return |
||
535 | * @param string $lang preferred language |
||
536 | * @return EasyRdf\Literal label as an EasyRdf\Literal object, or null if not found |
||
537 | */ |
||
538 | public function getResourceLabel($res, $lang) |
||
550 | |||
551 | public function getResourceFromUri($uri) |
||
568 | |||
569 | /** |
||
570 | * Returns a SPARQL endpoint object. |
||
571 | * @param string $dialect eg. 'JenaText'. |
||
572 | * @param string $endpoint url address of endpoint |
||
573 | * @param string $graph uri for the target graph. |
||
574 | */ |
||
575 | public function getSparqlImplementation($dialect, $endpoint, $graph) |
||
581 | |||
582 | /** |
||
583 | * Returns a SPARQL endpoint object using the default implementation set in the config.ttl. |
||
584 | */ |
||
585 | public function getDefaultSparql() |
||
589 | |||
590 | } |
||
591 |
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.