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 SchemaPluginBase 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 SchemaPluginBase, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
21 | abstract class SchemaPluginBase extends PluginBase implements SchemaPluginInterface, SchemaBuilderInterface, ContainerFactoryPluginInterface, CacheableDependencyInterface { |
||
22 | |||
23 | /** |
||
24 | * The field plugin manager. |
||
25 | * |
||
26 | * @var \Drupal\graphql\Plugin\FieldPluginManager |
||
27 | */ |
||
28 | protected $fieldManager; |
||
29 | |||
30 | /** |
||
31 | * The mutation plugin manager. |
||
32 | * |
||
33 | * @var \Drupal\graphql\Plugin\MutationPluginManager |
||
34 | */ |
||
35 | protected $mutationManager; |
||
36 | |||
37 | /** |
||
38 | * The subscription plugin manager. |
||
39 | * |
||
40 | * @var \Drupal\graphql\Plugin\SubscriptionPluginManager |
||
41 | */ |
||
42 | protected $subscriptionManager; |
||
43 | |||
44 | /** |
||
45 | * The type manager aggregator service. |
||
46 | * |
||
47 | * @var \Drupal\graphql\Plugin\TypePluginManagerAggregator |
||
48 | */ |
||
49 | protected $typeManagers; |
||
50 | |||
51 | /** |
||
52 | * Static cache of field definitions. |
||
53 | * |
||
54 | * @var array |
||
55 | */ |
||
56 | protected $fields = []; |
||
57 | |||
58 | /** |
||
59 | * Static cache of mutation definitions. |
||
60 | * |
||
61 | * @var array |
||
62 | */ |
||
63 | protected $mutations = []; |
||
64 | |||
65 | /** |
||
66 | * Static cache of subscription definitions. |
||
67 | * |
||
68 | * @var array |
||
69 | */ |
||
70 | protected $subscriptions = []; |
||
71 | |||
72 | /** |
||
73 | * Static cache of type instances. |
||
74 | * |
||
75 | * @var array |
||
76 | */ |
||
77 | protected $types = []; |
||
78 | |||
79 | /** |
||
80 | * {@inheritdoc} |
||
81 | */ |
||
82 | View Code Duplication | public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { |
|
93 | |||
94 | /** |
||
95 | * SchemaPluginBase constructor. |
||
96 | * |
||
97 | * @param array $configuration |
||
98 | * The plugin configuration array. |
||
99 | * @param string $pluginId |
||
100 | * The plugin id. |
||
101 | * @param array $pluginDefinition |
||
102 | * The plugin definition array. |
||
103 | * @param \Drupal\graphql\Plugin\FieldPluginManager $fieldManager |
||
104 | * The field plugin manager. |
||
105 | * @param \Drupal\graphql\Plugin\MutationPluginManager $mutationManager |
||
106 | * The mutation plugin manager. |
||
107 | * @param \Drupal\graphql\Plugin\SubscriptionPluginManager $subscriptionManager |
||
108 | * The subscription plugin manager. |
||
109 | * @param \Drupal\graphql\Plugin\TypePluginManagerAggregator $typeManagers |
||
110 | * The type manager aggregator service. |
||
111 | */ |
||
112 | View Code Duplication | public function __construct( |
|
127 | |||
128 | /** |
||
129 | * {@inheritdoc} |
||
130 | */ |
||
131 | public function getSchema() { |
||
169 | |||
170 | /** |
||
171 | * {@inheritdoc} |
||
172 | */ |
||
173 | public function hasFields($type) { |
||
176 | |||
177 | /** |
||
178 | * {@inheritdoc} |
||
179 | */ |
||
180 | public function hasMutations() { |
||
183 | |||
184 | /** |
||
185 | * {@inheritdoc} |
||
186 | */ |
||
187 | public function hasSubscriptions() { |
||
190 | |||
191 | /** |
||
192 | * {@inheritdoc} |
||
193 | */ |
||
194 | public function hasType($name) { |
||
197 | |||
198 | /** |
||
199 | * {@inheritdoc} |
||
200 | */ |
||
201 | public function getFields($type) { |
||
213 | |||
214 | /** |
||
215 | * {@inheritdoc} |
||
216 | */ |
||
217 | public function getMutations() { |
||
220 | |||
221 | /** |
||
222 | * {@inheritdoc} |
||
223 | */ |
||
224 | public function getSubscriptions() { |
||
227 | |||
228 | /** |
||
229 | * {@inheritdoc} |
||
230 | */ |
||
231 | public function getTypes() { |
||
236 | |||
237 | /** |
||
238 | * {@inheritdoc} |
||
239 | */ |
||
240 | public function getSubTypes($name) { |
||
244 | |||
245 | /** |
||
246 | * {@inheritdoc} |
||
247 | */ |
||
248 | public function resolveType($name, $value, ResolveContext $context, ResolveInfo $info) { |
||
266 | |||
267 | /** |
||
268 | * {@inheritdoc} |
||
269 | */ |
||
270 | public function getType($name) { |
||
285 | |||
286 | /** |
||
287 | * {@inheritdoc} |
||
288 | */ |
||
289 | public function processMutations($mutations) { |
||
292 | |||
293 | /** |
||
294 | * {@inheritdoc} |
||
295 | */ |
||
296 | public function processSubscriptions($subscriptions) { |
||
299 | |||
300 | /** |
||
301 | * {@inheritdoc} |
||
302 | */ |
||
303 | public function processFields($fields) { |
||
306 | |||
307 | /** |
||
308 | * {@inheritdoc} |
||
309 | */ |
||
310 | public function processArguments($args) { |
||
317 | |||
318 | /** |
||
319 | * {@inheritdoc} |
||
320 | */ |
||
321 | public function processType($type) { |
||
328 | |||
329 | /** |
||
330 | * Retrieves the type instance for the given reference. |
||
331 | * |
||
332 | * @param array $type |
||
333 | * The type reference. |
||
334 | * |
||
335 | * @return \GraphQL\Type\Definition\Type |
||
336 | * The type instance. |
||
337 | */ |
||
338 | protected function buildType($type) { |
||
347 | |||
348 | /** |
||
349 | * Retrieves the field definition for a given field reference. |
||
350 | * |
||
351 | * @param array $field |
||
352 | * The type reference. |
||
353 | * |
||
354 | * @return array |
||
355 | * The field definition. |
||
356 | */ |
||
357 | View Code Duplication | protected function buildField($field) { |
|
365 | |||
366 | /** |
||
367 | * Retrieves the mutation definition for a given field reference. |
||
368 | * |
||
369 | * @param array $mutation |
||
370 | * The mutation reference. |
||
371 | * |
||
372 | * @return array |
||
373 | * The mutation definition. |
||
374 | */ |
||
375 | View Code Duplication | protected function buildMutation($mutation) { |
|
383 | |||
384 | /** |
||
385 | * Retrieves the subscription definition for a given field reference. |
||
386 | * |
||
387 | * @param array $mutation |
||
388 | * The subscription reference. |
||
389 | * |
||
390 | * @return array |
||
391 | * The subscription definition. |
||
392 | */ |
||
393 | View Code Duplication | protected function buildSubscription($subscription) { |
|
401 | |||
402 | /** |
||
403 | * {@inheritdoc} |
||
404 | */ |
||
405 | public function getCacheContexts() { |
||
408 | |||
409 | /** |
||
410 | * {@inheritdoc} |
||
411 | */ |
||
412 | public function getCacheTags() { |
||
415 | |||
416 | /** |
||
417 | * {@inheritdoc} |
||
418 | */ |
||
419 | public function getCacheMaxAge() { |
||
422 | } |
||
423 |
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.