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:
| 1 | <?php |
||
| 18 | class SubFamilyLogController extends Controller |
||
| 19 | { |
||
| 20 | /** |
||
| 21 | * Lists all SubFamilyLog entities. |
||
| 22 | * |
||
| 23 | * @Route("/", name="admin_subfamilylog") |
||
| 24 | * @Method("GET") |
||
| 25 | * @Template() |
||
| 26 | */ |
||
| 27 | public function indexAction(Request $request) |
||
| 38 | |||
| 39 | /** |
||
| 40 | * Finds and displays a SubFamilyLog entity. |
||
| 41 | * |
||
| 42 | * @Route("/{slug}/show", name="admin_subfamilylog_show") |
||
| 43 | * @Method("GET") |
||
| 44 | * @Template() |
||
| 45 | */ |
||
| 46 | public function showAction(SubFamilyLog $subfamilylog) |
||
| 55 | |||
| 56 | /** |
||
| 57 | * Displays a form to create a new SubFamilyLog entity. |
||
| 58 | * |
||
| 59 | * @Route("/new", name="admin_subfamilylog_new") |
||
| 60 | * @Method("GET") |
||
| 61 | * @Template() |
||
| 62 | */ |
||
| 63 | public function newAction() |
||
| 73 | |||
| 74 | /** |
||
| 75 | * Creates a new SubFamilyLog entity. |
||
| 76 | * |
||
| 77 | * @Route("/create", name="admin_subfamilylog_create") |
||
| 78 | * @Method("POST") |
||
| 79 | * @Template("AppBundle:SubFamilyLog:new.html.twig") |
||
| 80 | */ |
||
| 81 | public function createAction(Request $request) |
||
| 104 | |||
| 105 | /** |
||
| 106 | * Displays a form to edit an existing SubFamilyLog entity. |
||
| 107 | * |
||
| 108 | * @Route("/{slug}/edit", name="admin_subfamilylog_edit") |
||
| 109 | * @Method("GET") |
||
| 110 | * @Template() |
||
| 111 | */ |
||
| 112 | View Code Duplication | public function editAction(SubFamilyLog $subfamilylog) |
|
| 129 | |||
| 130 | /** |
||
| 131 | * Edits an existing SubFamilyLog entity. |
||
| 132 | * |
||
| 133 | * @Route("/{slug}/update", name="admin_subfamilylog_update") |
||
| 134 | * @Method("PUT") |
||
| 135 | * @Template("AppBundle:SubFamilyLog:edit.html.twig") |
||
| 136 | */ |
||
| 137 | View Code Duplication | public function updateAction(SubFamilyLog $subfamilylog, Request $request) |
|
| 159 | |||
| 160 | |||
| 161 | /** |
||
| 162 | * Save order. |
||
| 163 | * |
||
| 164 | * @Route("/order/{field}/{type}", name="admin_subfamilylog_sort") |
||
| 165 | */ |
||
| 166 | public function sortAction($field, $type) |
||
| 172 | |||
| 173 | /** |
||
| 174 | * @param string $name session name |
||
| 175 | * @param string $field field name |
||
| 176 | * @param string $type sort type ("ASC"/"DESC") |
||
| 177 | */ |
||
| 178 | protected function setOrder($name, $field, $type = 'ASC') |
||
| 185 | |||
| 186 | /** |
||
| 187 | * @param string $name |
||
| 188 | * @return array |
||
| 189 | */ |
||
| 190 | protected function getOrder($name) |
||
| 196 | |||
| 197 | /** |
||
| 198 | * @param QueryBuilder $qb |
||
| 199 | * @param string $name |
||
| 200 | */ |
||
| 201 | View Code Duplication | protected function addQueryBuilderSort(\Doctrine\ORM\QueryBuilder $qb, $name) |
|
| 208 | |||
| 209 | /** |
||
| 210 | * Deletes a SubFamilyLog entity. |
||
| 211 | * |
||
| 212 | * @Route("/{id}/delete", name="admin_subfamilylog_delete", requirements={"id"="\d+"}) |
||
| 213 | * @Method("DELETE") |
||
| 214 | */ |
||
| 215 | public function deleteAction(SubFamilyLog $subfamilylog, Request $request) |
||
| 226 | |||
| 227 | /** |
||
| 228 | * Create Delete form |
||
| 229 | * |
||
| 230 | * @param integer $id |
||
| 231 | * @param string $route |
||
| 232 | * @return \Symfony\Component\Form\Form |
||
| 233 | */ |
||
| 234 | protected function createDeleteForm($id, $route) |
||
| 242 | } |
||
| 243 |
Let’s take a look at an example:
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.
Available Fixes
Change the type-hint for the parameter:
Add an additional type-check:
Add the method to the interface: