Complex classes like PostVotePost 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 PostVotePost, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
23 | class PostVotePost implements InputFilterAwareInterface, Translatable, \JsonSerializable |
||
24 | { |
||
25 | /** |
||
26 | * @Gedmo\Locale |
||
27 | * Used locale to override Translation listener`s locale |
||
28 | * this is not a mapped field of entity metadata, just a simple property |
||
29 | */ |
||
30 | protected $locale; |
||
31 | |||
32 | protected $inputFilter; |
||
33 | |||
34 | /** |
||
35 | * @ORM\Id |
||
36 | * @ORM\Column(type="integer"); |
||
37 | * @ORM\GeneratedValue(strategy="AUTO") |
||
38 | */ |
||
39 | protected $id; |
||
40 | |||
41 | /** |
||
42 | * @ORM\ManyToOne(targetEntity="PostVote", inversedBy="posts") |
||
43 | * @ORM\JoinColumn(name="postvote_id", referencedColumnName="id", onDelete="CASCADE") |
||
44 | */ |
||
45 | protected $postvote; |
||
46 | |||
47 | /** |
||
48 | * @ORM\ManyToOne(targetEntity="PlaygroundUser\Entity\User") |
||
49 | * @ORM\JoinColumn(name="user_id", referencedColumnName="user_id", onDelete="CASCADE") |
||
50 | **/ |
||
51 | protected $user; |
||
52 | |||
53 | /** |
||
54 | * @ORM\ManyToOne(targetEntity="Entry") |
||
55 | * @ORM\JoinColumn(name="entry_id",referencedColumnName="id",onDelete="CASCADE") |
||
56 | **/ |
||
57 | protected $entry; |
||
58 | |||
59 | /** |
||
60 | * @ORM\OneToMany(targetEntity="PostVoteVote", mappedBy="post") |
||
61 | * @ORM\OrderBy({"createdAt"="DESC"}) |
||
62 | */ |
||
63 | private $votes; |
||
64 | |||
65 | /** |
||
66 | * @ORM\OneToMany(targetEntity="PostVoteComment", mappedBy="post") |
||
67 | * @ORM\OrderBy({"createdAt"="DESC"}) |
||
68 | */ |
||
69 | private $comments; |
||
70 | |||
71 | /** |
||
72 | * @ORM\OneToMany(targetEntity="PostVoteView", mappedBy="post") |
||
73 | * @ORM\OrderBy({"createdAt"="DESC"}) |
||
74 | */ |
||
75 | private $views; |
||
76 | |||
77 | /** |
||
78 | * @ORM\OneToMany(targetEntity="PostVotePostElement", mappedBy="post", cascade={"persist","remove"}) |
||
79 | */ |
||
80 | private $postElements; |
||
81 | |||
82 | /** |
||
83 | * # of shares (FB, Twitter, mails...) |
||
84 | * @ORM\Column(type="integer", nullable=false) |
||
85 | */ |
||
86 | |||
87 | /** |
||
88 | * @ORM\OneToMany(targetEntity="PostVoteShare", mappedBy="post") |
||
89 | * @ORM\OrderBy({"createdAt"="DESC"}) |
||
90 | */ |
||
91 | protected $shares; |
||
92 | |||
93 | /** |
||
94 | * values : |
||
95 | * 0 : draft |
||
96 | * 1 : user confirmed |
||
97 | * 2 : admin accepted |
||
98 | * 8 : user rejected |
||
99 | * 9 : admin rejected |
||
100 | * |
||
101 | * @ORM\Column(type="integer", nullable=false) |
||
102 | */ |
||
103 | protected $status = 0; |
||
104 | |||
105 | /** |
||
106 | * @ORM\Column(type="boolean", nullable=true) |
||
107 | */ |
||
108 | protected $pushed = 0; |
||
109 | |||
110 | /** |
||
111 | * @ORM\Column(name="created_at", type="datetime") |
||
112 | */ |
||
113 | protected $createdAt; |
||
114 | |||
115 | /** |
||
116 | * @ORM\Column(name="updated_at", type="datetime") |
||
117 | */ |
||
118 | protected $updatedAt; |
||
119 | |||
120 | public function __construct() |
||
128 | |||
129 | /** |
||
130 | * @PrePersist |
||
131 | */ |
||
132 | public function createChrono() |
||
137 | |||
138 | /** |
||
139 | * @PreUpdate |
||
140 | */ |
||
141 | public function updateChrono() |
||
145 | |||
146 | /** |
||
147 | * @return the unknown_type |
||
148 | */ |
||
149 | public function getId() |
||
153 | |||
154 | /** |
||
155 | * @param unknown_type $id |
||
156 | */ |
||
157 | public function setId($id) |
||
163 | |||
164 | /** |
||
165 | * @return the unknown_type |
||
166 | */ |
||
167 | public function getPostvote() |
||
171 | |||
172 | /** |
||
173 | * @param unknown_type $postvote |
||
174 | */ |
||
175 | public function setPostvote($postvote) |
||
182 | |||
183 | /** |
||
184 | * @return the unknown_type |
||
185 | */ |
||
186 | public function getUser() |
||
190 | |||
191 | /** |
||
192 | * @param unknown_type $user |
||
193 | */ |
||
194 | public function setUser($user) |
||
200 | |||
201 | /** |
||
202 | * @return boolean |
||
203 | */ |
||
204 | public function getEntry() |
||
208 | |||
209 | /** |
||
210 | * @param boolean $entry |
||
211 | */ |
||
212 | public function setEntry($entry) |
||
218 | |||
219 | /** |
||
220 | * Add an entry to the post. |
||
221 | * |
||
222 | * @param PostVotePostEntry $postElement |
||
223 | * |
||
224 | * @return void |
||
225 | */ |
||
226 | public function addPostElement($postElement) |
||
231 | |||
232 | /** |
||
233 | * @return ArrayCollection unknown_type |
||
234 | */ |
||
235 | public function getPostElements() |
||
239 | |||
240 | /** |
||
241 | */ |
||
242 | public function setPostElements($postElements) |
||
248 | |||
249 | /** |
||
250 | * Add an entry to the vote. |
||
251 | * |
||
252 | * @param PostVoteVote $vote |
||
253 | * |
||
254 | * @return void |
||
255 | */ |
||
256 | public function addVote($vote) |
||
260 | |||
261 | /** |
||
262 | * @return the unknown_type |
||
263 | */ |
||
264 | public function getVotes() |
||
268 | |||
269 | /** |
||
270 | * @param unknown_type $votes |
||
271 | */ |
||
272 | public function setVotes($votes) |
||
278 | |||
279 | /** |
||
280 | * Add an entry to the comment. |
||
281 | * |
||
282 | * @param PostVoteComment $comment |
||
283 | * |
||
284 | * @return void |
||
285 | */ |
||
286 | public function addComment(PostVoteComment $comment) |
||
290 | |||
291 | /** |
||
292 | * @return the collection of comments. You can filter on it based on one or more categories |
||
293 | */ |
||
294 | public function getComments($category = null) |
||
306 | |||
307 | /** |
||
308 | * @param unknown_type $comments |
||
309 | */ |
||
310 | public function setComments($comments) |
||
316 | |||
317 | public function addComments(ArrayCollection $comments) |
||
324 | |||
325 | public function removeComments(\Doctrine\Common\Collections\Collection $comments) |
||
332 | |||
333 | /** |
||
334 | * @return integer unknown_type |
||
335 | */ |
||
336 | public function getShares() |
||
340 | |||
341 | /** |
||
342 | * @param unknown_shares $shares |
||
343 | */ |
||
344 | public function setShares($shares) |
||
350 | |||
351 | /** |
||
352 | * Add an entry to the share. |
||
353 | * |
||
354 | * @param PostVoteShare $share |
||
355 | * |
||
356 | * @return void |
||
357 | */ |
||
358 | public function addShare(PostVoteShare $share) |
||
362 | |||
363 | public function addShares(ArrayCollection $shares) |
||
370 | |||
371 | public function removeShares(\Doctrine\Common\Collections\Collection $shares) |
||
378 | |||
379 | /** |
||
380 | * Add an entry to the view. |
||
381 | * |
||
382 | * @param PostVoteView $view |
||
383 | * |
||
384 | * @return void |
||
385 | */ |
||
386 | public function addView(PostVoteView $view) |
||
390 | |||
391 | /** |
||
392 | * @return the collection of views. You can filter on it based on one or more categories |
||
393 | */ |
||
394 | public function getViews() |
||
398 | |||
399 | /** |
||
400 | * @param unknown_type $views |
||
401 | */ |
||
402 | public function setViews($views) |
||
408 | |||
409 | public function addViews(ArrayCollection $views) |
||
416 | |||
417 | public function removeViews(\Doctrine\Common\Collections\Collection $views) |
||
424 | |||
425 | /** |
||
426 | * @return integer unknown_type |
||
427 | */ |
||
428 | public function getStatus() |
||
432 | |||
433 | /** |
||
434 | * @param unknown_status $status |
||
435 | */ |
||
436 | public function setStatus($status) |
||
442 | |||
443 | /** |
||
444 | * @return integer |
||
445 | */ |
||
446 | public function isPushed() |
||
450 | |||
451 | /** |
||
452 | * @param bool $pushed |
||
453 | * @return PostVotePost |
||
454 | */ |
||
455 | public function setPushed($pushed) |
||
460 | |||
461 | /** |
||
462 | * @return the unknown_type |
||
463 | */ |
||
464 | public function getCreatedAt() |
||
468 | |||
469 | /** |
||
470 | * @param unknown_type $createdAt |
||
471 | */ |
||
472 | public function setCreatedAt($createdAt) |
||
478 | |||
479 | /** |
||
480 | * @return the unknown_type |
||
481 | */ |
||
482 | public function getUpdatedAt() |
||
486 | |||
487 | /** |
||
488 | * @param unknown_type $updatedAt |
||
489 | */ |
||
490 | public function setUpdatedAt($updatedAt) |
||
496 | |||
497 | /** |
||
498 | * @return ArrayCollection unknown_type |
||
499 | */ |
||
500 | public function getPostElementsAsArray() |
||
510 | |||
511 | /** |
||
512 | * Convert the object to an array. |
||
513 | * |
||
514 | * @return array |
||
515 | */ |
||
516 | public function getArrayCopy() |
||
526 | |||
527 | /** |
||
528 | * Convert the object to json. |
||
529 | * |
||
530 | * @return array |
||
531 | */ |
||
532 | public function jsonSerialize() |
||
536 | |||
537 | /** |
||
538 | * Populate from an array. |
||
539 | * |
||
540 | * @param array $data |
||
541 | */ |
||
542 | public function populate($data = array()) |
||
545 | |||
546 | public function setInputFilter(InputFilterInterface $inputFilter) |
||
550 | |||
551 | public function getInputFilter() |
||
572 | |||
573 | public function setTranslatableLocale($locale) |
||
577 | } |
||
578 |
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.
Let’s take a look at an example:
Our function
my_function
expects aPost
object, and outputs the author of the post. The base classPost
returns a simple string and outputting a simple string will work just fine. However, the child classBlogPost
which is a sub-type ofPost
instead decided to return anobject
, and is therefore violating the SOLID principles. If aBlogPost
were passed tomy_function
, PHP would not complain, but ultimately fail when executing thestrtoupper
call in its body.