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 ResourceType 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 ResourceType, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
32 | class ResourceType |
||
33 | { |
||
34 | /** |
||
35 | * Name of the resource described by this class instance. |
||
36 | * |
||
37 | * @var string |
||
38 | */ |
||
39 | private $_name; |
||
40 | |||
41 | /** |
||
42 | * Namespace name in which resource described by this class instance |
||
43 | * belongs to. |
||
44 | * |
||
45 | * @var string |
||
46 | */ |
||
47 | private $_namespaceName; |
||
48 | |||
49 | /** |
||
50 | * The fully qualified name of the resource described by this class instance. |
||
51 | * |
||
52 | * @var string |
||
53 | */ |
||
54 | private $_fullName; |
||
55 | |||
56 | /** |
||
57 | * The type the resource described by this class instance. |
||
58 | * Note: either Entity or Complex Type |
||
59 | * |
||
60 | * @var ResourceTypeKind |
||
61 | */ |
||
62 | private $_resourceTypeKind; |
||
63 | |||
64 | /** |
||
65 | * @var boolean |
||
66 | */ |
||
67 | private $_abstractType; |
||
68 | |||
69 | /** |
||
70 | * Refrence to ResourceType instance for base type, if any. |
||
71 | * |
||
72 | * @var ResourceType |
||
73 | */ |
||
74 | private $_baseType; |
||
75 | |||
76 | /** |
||
77 | * Collection of ResourceProperty for all properties declared on the |
||
78 | * resource described by this class instance (This does not include |
||
79 | * base type properties). |
||
80 | * |
||
81 | * @var ResourceProperty[] indexed by name |
||
82 | */ |
||
83 | private $_propertiesDeclaredOnThisType = array(); |
||
84 | |||
85 | /** |
||
86 | * Collection of ResourceStreamInfo for all named streams declared on |
||
87 | * the resource described by this class instance (This does not include |
||
88 | * base type properties). |
||
89 | * |
||
90 | * @var ResourceStreamInfo[] indexed by name |
||
91 | */ |
||
92 | private $_namedStreamsDeclaredOnThisType = array(); |
||
93 | |||
94 | /** |
||
95 | * Collection of ReflectionProperty instances for each property declared |
||
96 | * on this type |
||
97 | * |
||
98 | * @var array(ResourceProperty, ReflectionProperty) |
||
99 | */ |
||
100 | private $_propertyInfosDeclaredOnThisType = array(); |
||
|
|||
101 | |||
102 | /** |
||
103 | * Collection of ResourceProperty for all properties declared on this type. |
||
104 | * and base types. |
||
105 | * |
||
106 | * @var ResourceProperty[] indexed by name |
||
107 | */ |
||
108 | private $_allProperties = array(); |
||
109 | |||
110 | /** |
||
111 | * Collection of ResourceStreamInfo for all named streams declared on this type. |
||
112 | * and base types |
||
113 | * |
||
114 | * @var ResourceStreamInfo[] |
||
115 | */ |
||
116 | private $_allNamedStreams = array(); |
||
117 | |||
118 | /** |
||
119 | * Collection of properties which has etag defined subset of $_allProperties |
||
120 | * @var ResourceProperty[] |
||
121 | */ |
||
122 | private $_etagProperties = array(); |
||
123 | |||
124 | /** |
||
125 | * Collection of key properties subset of $_allProperties |
||
126 | * |
||
127 | * @var ResourceProperty[] |
||
128 | */ |
||
129 | private $_keyProperties = array(); |
||
130 | |||
131 | /** |
||
132 | * Whether the resource type described by this class instance is a MLE or not |
||
133 | * |
||
134 | * @var boolean |
||
135 | */ |
||
136 | private $_isMediaLinkEntry = false; |
||
137 | |||
138 | /** |
||
139 | * Whether the resource type described by this class instance has bag properties |
||
140 | * Note: This has been initialized with null, later in hasBagProperty method, |
||
141 | * this flag will be set to boolean value |
||
142 | * |
||
143 | * @var boolean |
||
144 | */ |
||
145 | private $_hasBagProperty = null; |
||
146 | |||
147 | /** |
||
148 | * Whether the resource type described by this class instance has named streams |
||
149 | * Note: This has been intitialized with null, later in hasNamedStreams method, |
||
150 | * this flag will be set to boolean value |
||
151 | * |
||
152 | * @var boolean |
||
153 | */ |
||
154 | private $_hasNamedStreams = null; |
||
155 | |||
156 | /** |
||
157 | * ReflectionClass (for complex/Entity) or IType (for Primitive) instance for |
||
158 | * the resource (type) described by this class instance |
||
159 | * |
||
160 | * @var \ReflectionClass|IType |
||
161 | */ |
||
162 | private $_type; |
||
163 | |||
164 | /** |
||
165 | * To store any custom information related to this class instance |
||
166 | * |
||
167 | * @var Object |
||
168 | */ |
||
169 | private $_customState; |
||
170 | |||
171 | /** |
||
172 | * Array to detect looping in bag's complex type |
||
173 | * |
||
174 | * @var array |
||
175 | */ |
||
176 | private $_arrayToDetectLoopInComplexBag; |
||
177 | |||
178 | /** |
||
179 | * Create new instance of ResourceType |
||
180 | * |
||
181 | * @param \ReflectionClass|IType $instanceType Instance type for the resource, |
||
182 | * for entity and |
||
183 | * complex this will |
||
184 | * be 'ReflectionClass' and for |
||
185 | * primitive type this |
||
186 | * will be IType |
||
187 | * @param ResourceTypeKind $resourceTypeKind Kind of resource (Entity, Complex or Primitive) |
||
188 | * @param string $name Name of the resource |
||
189 | * @param string $namespaceName Namespace of the resource |
||
190 | * @param ResourceType $baseType Base type of the resource, if exists |
||
191 | * |
||
192 | * @param boolean $isAbstract Whether resource is abstract |
||
193 | * |
||
194 | * @throws \InvalidArgumentException |
||
195 | */ |
||
196 | public function __construct( |
||
243 | |||
244 | /** |
||
245 | * Get reference to ResourceType for base class |
||
246 | * |
||
247 | * @return ResourceType |
||
248 | */ |
||
249 | public function getBaseType() |
||
253 | |||
254 | /** |
||
255 | * To check whether this resource type has base type |
||
256 | * |
||
257 | * @return boolean True if base type is defined, false otherwise |
||
258 | */ |
||
259 | public function hasBaseType() |
||
263 | |||
264 | /** |
||
265 | * To get custom state object for this type |
||
266 | * |
||
267 | * @return object |
||
268 | */ |
||
269 | public function getCustomState() |
||
273 | |||
274 | /** |
||
275 | * To set custom state object for this type |
||
276 | * |
||
277 | * @param Object $object The custom object. |
||
278 | * |
||
279 | * @return void |
||
280 | */ |
||
281 | public function setCustomState($object) |
||
285 | |||
286 | /** |
||
287 | * Get the instance type. If the resource type describes a complex or entity type |
||
288 | * then this function returns refernece to ReflectionClass instance for the type. |
||
289 | * If resource type describes a primitive type then this function returns ITYpe. |
||
290 | * |
||
291 | * @return \ReflectionClass|IType |
||
292 | */ |
||
293 | public function getInstanceType() |
||
297 | |||
298 | /** |
||
299 | * Get name of the type described by this resource type |
||
300 | * |
||
301 | * @return string |
||
302 | */ |
||
303 | public function getName() |
||
307 | |||
308 | /** |
||
309 | * Get the namespace under which the type described by this resource type is |
||
310 | * defined. |
||
311 | * |
||
312 | * @return string |
||
313 | */ |
||
314 | public function getNamespace() |
||
318 | |||
319 | /** |
||
320 | * Get full name (namespacename.typename) of the type described by this resource |
||
321 | * type. |
||
322 | * |
||
323 | * @return string |
||
324 | */ |
||
325 | public function getFullName() |
||
329 | |||
330 | /** |
||
331 | * To check whether the type described by this resource type is abstract or not |
||
332 | * |
||
333 | * @return boolean True if type is abstract else False |
||
334 | */ |
||
335 | public function isAbstract() |
||
339 | |||
340 | /** |
||
341 | * To get the kind of type described by this resource class |
||
342 | * |
||
343 | * @return ResourceTypeKind |
||
344 | */ |
||
345 | public function getResourceTypeKind() |
||
349 | |||
350 | /** |
||
351 | * To check whether the type described by this resource type is MLE |
||
352 | * |
||
353 | * @return boolean True if type is MLE else False |
||
354 | */ |
||
355 | public function isMediaLinkEntry() |
||
359 | |||
360 | /** |
||
361 | * Set the resource type as MLE or non-MLE |
||
362 | * |
||
363 | * @param boolean $isMLE True to set as MLE, false for non-MLE |
||
364 | * |
||
365 | * @return void |
||
366 | */ |
||
367 | public function setMediaLinkEntry($isMLE) |
||
377 | |||
378 | /** |
||
379 | * Add a property belongs to this resource type instance |
||
380 | * |
||
381 | * @param ResourceProperty $property Property to add |
||
382 | * |
||
383 | * @throws InvalidOperationException |
||
384 | * @return void |
||
385 | */ |
||
386 | public function addProperty(ResourceProperty $property) |
||
437 | |||
438 | /** |
||
439 | * Get collection properties belongs to this resource type (excluding base class |
||
440 | * properties). This function returns empty array in case of resource type |
||
441 | * for primitive types. |
||
442 | * |
||
443 | * @return ResourceProperty[] |
||
444 | */ |
||
445 | public function getPropertiesDeclaredOnThisType() |
||
449 | |||
450 | /** |
||
451 | * Get collection properties belongs to this resource type including base class |
||
452 | * properties. This function returns empty array in case of resource type |
||
453 | * for primitive types. |
||
454 | * |
||
455 | * @return ResourceProperty[] |
||
456 | */ |
||
457 | public function getAllProperties() |
||
471 | |||
472 | /** |
||
473 | * Get collection key properties belongs to this resource type. This |
||
474 | * function returns non-empty array only for resource type representing |
||
475 | * an entity type. |
||
476 | * |
||
477 | * @return ResourceProperty[] |
||
478 | */ |
||
479 | public function getKeyProperties() |
||
498 | |||
499 | /** |
||
500 | * Get collection of e-tag properties belongs to this type. |
||
501 | * |
||
502 | * @return ResourceProperty[] |
||
503 | */ |
||
504 | public function getETagProperties() |
||
518 | |||
519 | /** |
||
520 | * To check this type has any eTag properties |
||
521 | * |
||
522 | * @return boolean |
||
523 | */ |
||
524 | public function hasETagProperties() |
||
529 | |||
530 | /** |
||
531 | * Try to get ResourceProperty for a property defined for this resource type |
||
532 | * excluding base class properties |
||
533 | * |
||
534 | * @param string $propertyName The name of the property to resolve. |
||
535 | * |
||
536 | * @return ResourceProperty|null |
||
537 | */ |
||
538 | public function resolvePropertyDeclaredOnThisType($propertyName) |
||
546 | |||
547 | /** |
||
548 | * Try to get ResourceProperty for a property defined for this resource type |
||
549 | * including base class properties |
||
550 | * |
||
551 | * @param string $propertyName The name of the property to resolve. |
||
552 | * |
||
553 | * @return ResourceProperty|null |
||
554 | */ |
||
555 | public function resolveProperty($propertyName) |
||
563 | |||
564 | /** |
||
565 | * Add a named stream belongs to this resource type instance |
||
566 | * |
||
567 | * @param ResourceStreamInfo $namedStream ResourceStreamInfo instance describing the named stream to add. |
||
568 | * |
||
569 | * @return void |
||
570 | * |
||
571 | * @throws InvalidOperationException |
||
572 | */ |
||
573 | public function addNamedStream(ResourceStreamInfo $namedStream) |
||
603 | |||
604 | /** |
||
605 | * Get collection of ResourceStreamInfo describing the named streams belongs |
||
606 | * to this resource type (excluding base class properties) |
||
607 | * |
||
608 | * @return ResourceStreamInfo[] |
||
609 | */ |
||
610 | public function getNamedStreamsDeclaredOnThisType() |
||
614 | |||
615 | /** |
||
616 | * Get collection of ResourceStreamInfo describing the named streams belongs |
||
617 | * to this resource type including base class named streams. |
||
618 | * |
||
619 | * @return ResourceStreamInfo[] |
||
620 | */ |
||
621 | public function getAllNamedStreams() |
||
637 | |||
638 | /** |
||
639 | * Try to get ResourceStreamInfo for a named stream defined for this |
||
640 | * resource type excluding base class named streams |
||
641 | * |
||
642 | * @param string $namedStreamName Name of the named stream to resolve. |
||
643 | * |
||
644 | * @return ResourceStreamInfo|null |
||
645 | */ |
||
646 | public function tryResolveNamedStreamDeclaredOnThisTypeByName($namedStreamName) |
||
654 | |||
655 | /** |
||
656 | * Try to get ResourceStreamInfo for a named stream defined for this resource |
||
657 | * type including base class named streams |
||
658 | * |
||
659 | * @param string $namedStreamName Name of the named stream to resolve. |
||
660 | * |
||
661 | * @return ResourceStreamInfo|NULL |
||
662 | */ |
||
663 | public function tryResolveNamedStreamByName($namedStreamName) |
||
671 | |||
672 | /** |
||
673 | * Check this resource type instance has named stream associated with it |
||
674 | * Note: This is an internal method used by library. Devs don't use this. |
||
675 | * |
||
676 | * @return boolean true if resource type instance has named stream else false |
||
677 | */ |
||
678 | public function hasNamedStream() |
||
692 | |||
693 | /** |
||
694 | * Check this resource type instance has bag property associated with it |
||
695 | * Note: This is an internal method used by library. Devs don't use this. |
||
696 | * |
||
697 | * @param array &$arrayToDetectLoopInComplexType array for detecting loop. |
||
698 | * |
||
699 | * @return boolean true if resource type instance has bag property else false |
||
700 | */ |
||
701 | public function hasBagProperty(&$arrayToDetectLoopInComplexType) |
||
774 | |||
775 | /** |
||
776 | * Validate the type |
||
777 | * |
||
778 | * @return void |
||
779 | * |
||
780 | * @throws InvalidOperationException |
||
781 | */ |
||
782 | public function validateType() |
||
793 | |||
794 | /** |
||
795 | * To check the type described by this resource type is assignable from |
||
796 | * a type described by another resource type. Or this type is a sub-type |
||
797 | * of (derived from the) given resource type |
||
798 | * |
||
799 | * @param ResourceType $resourceType Another resource type. |
||
800 | * |
||
801 | * @return boolean |
||
802 | */ |
||
803 | public function isAssignableFrom(ResourceType $resourceType) |
||
816 | |||
817 | /** |
||
818 | * Get predefined ResourceType for a primitive type |
||
819 | * |
||
820 | * @param EdmPrimitiveType $typeCode Typecode of primitive type |
||
821 | * |
||
822 | * @return ResourceType |
||
823 | * |
||
824 | * @throws InvalidArgumentException |
||
825 | */ |
||
826 | public static function getPrimitiveResourceType($typeCode) |
||
927 | } |
This check marks private properties in classes that are never used. Those properties can be removed.