Complex classes like YamlSerializationVisitor 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 YamlSerializationVisitor, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 35 | class YamlSerializationVisitor extends AbstractVisitor |
||
| 36 | { |
||
| 37 | public $writer; |
||
| 38 | |||
| 39 | private $navigator; |
||
| 40 | private $stack; |
||
| 41 | private $metadataStack; |
||
| 42 | private $currentMetadata; |
||
| 43 | |||
| 44 | 385 | public function __construct($namingStrategy, AccessorStrategyInterface $accessorStrategy = null) |
|
| 45 | { |
||
| 46 | 385 | parent::__construct($namingStrategy, $accessorStrategy); |
|
| 47 | |||
| 48 | 385 | $this->writer = new Writer(); |
|
| 49 | 385 | } |
|
| 50 | |||
| 51 | 98 | public function setNavigator(GraphNavigator $navigator) |
|
| 52 | { |
||
| 53 | 98 | $this->navigator = $navigator; |
|
| 54 | 98 | $this->writer->reset(); |
|
| 55 | 98 | $this->stack = new \SplStack; |
|
| 56 | 98 | $this->metadataStack = new \SplStack; |
|
| 57 | 98 | } |
|
| 58 | |||
| 59 | 10 | public function visitNull($data, array $type, Context $context) |
|
| 60 | { |
||
| 61 | 10 | if ('' === $this->writer->content) { |
|
| 62 | 6 | $this->writer->writeln('null'); |
|
| 63 | 6 | } |
|
| 64 | |||
| 65 | 10 | return 'null'; |
|
| 66 | } |
||
| 67 | |||
| 68 | 61 | public function visitString($data, array $type, Context $context) |
|
| 69 | { |
||
| 70 | 61 | $v = Inline::dump($data); |
|
| 71 | |||
| 72 | 61 | if ('' === $this->writer->content) { |
|
| 73 | 5 | $this->writer->writeln($v); |
|
| 74 | 5 | } |
|
| 75 | |||
| 76 | 61 | return $v; |
|
| 77 | } |
||
| 78 | |||
| 79 | /** |
||
| 80 | * @param array $data |
||
| 81 | * @param array $type |
||
| 82 | */ |
||
| 83 | 43 | public function visitArray($data, array $type, Context $context) |
|
| 84 | { |
||
| 85 | 43 | $isHash = isset($type['params'][1]); |
|
| 86 | |||
| 87 | 43 | $count = $this->writer->changeCount; |
|
| 88 | 43 | $isList = (isset($type['params'][0]) && !isset($type['params'][1])) |
|
| 89 | 43 | || array_keys($data) === range(0, count($data) - 1); |
|
| 90 | |||
| 91 | 43 | foreach ($data as $k => $v) { |
|
| 92 | 38 | if (null === $v && $context->shouldSerializeNull() !== true) { |
|
| 93 | 1 | continue; |
|
| 94 | } |
||
| 95 | |||
| 96 | 38 | if ($isList && !$isHash) { |
|
| 97 | 24 | $this->writer->writeln('-'); |
|
| 98 | 24 | } else { |
|
| 99 | 17 | $this->writer->writeln(Inline::dump($k) . ':'); |
|
| 100 | } |
||
| 101 | |||
| 102 | 38 | $this->writer->indent(); |
|
| 103 | |||
| 104 | 38 | if (null !== $v = $this->navigator->accept($v, $this->getElementType($type), $context)) { |
|
| 105 | 29 | $this->writer |
|
| 106 | 29 | ->rtrim(false) |
|
| 107 | 29 | ->writeln(' ' . $v); |
|
| 108 | 29 | } |
|
| 109 | |||
| 110 | 38 | $this->writer->outdent(); |
|
| 111 | 43 | } |
|
| 112 | |||
| 113 | 43 | if ($count === $this->writer->changeCount && isset($type['params'][1])) { |
|
| 114 | 2 | $this->writer |
|
| 115 | 2 | ->rtrim(false) |
|
| 116 | 2 | ->writeln(' {}'); |
|
| 117 | 43 | } elseif (empty($data)) { |
|
| 118 | 6 | $this->writer |
|
| 119 | 6 | ->rtrim(false) |
|
| 120 | 6 | ->writeln(' []'); |
|
| 121 | 6 | } |
|
| 122 | 43 | } |
|
| 123 | |||
| 124 | 6 | public function visitBoolean($data, array $type, Context $context) |
|
| 134 | |||
| 135 | 9 | public function visitDouble($data, array $type, Context $context) |
|
| 145 | |||
| 146 | 22 | public function visitInteger($data, array $type, Context $context) |
|
| 156 | |||
| 157 | 52 | public function startVisitingObject(ClassMetadata $metadata, $data, array $type, Context $context) |
|
| 160 | |||
| 161 | 52 | public function visitProperty(PropertyMetadata $metadata, $data, Context $context) |
|
| 162 | { |
||
| 163 | 52 | $v = $this->accessor->getValue($data, $metadata); |
|
| 164 | |||
| 165 | 51 | if (null === $v && $context->shouldSerializeNull() !== true) { |
|
| 198 | |||
| 199 | 51 | public function endVisitingObject(ClassMetadata $metadata, $data, array $type, Context $context) |
|
| 202 | |||
| 203 | 51 | public function setCurrentMetadata(PropertyMetadata $metadata) |
|
| 208 | |||
| 209 | 51 | public function revertCurrentMetadata() |
|
| 213 | |||
| 214 | public function getNavigator() |
||
| 218 | |||
| 219 | 95 | public function getResult() |
|
| 223 | } |
||
| 224 |