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 |
||
11 | class Model extends \Illuminate\Database\Eloquent\Model |
||
12 | { |
||
13 | /** |
||
14 | * Get the format for database stored dates. |
||
15 | * |
||
16 | * @return string |
||
17 | */ |
||
18 | protected function getDateFormat() |
||
22 | |||
23 | /** |
||
24 | * Get the table qualified key name. |
||
25 | * |
||
26 | * @return string |
||
27 | */ |
||
28 | public function getQualifiedKeyName() |
||
32 | |||
33 | /** |
||
34 | * Ensure Timestamps are returned in DateTime. |
||
35 | * |
||
36 | * @param \DateTime $value |
||
37 | * |
||
38 | * @return \DateTime |
||
39 | */ |
||
40 | protected function asDateTime($value) |
||
41 | { |
||
42 | if ($value instanceof DateTime) { |
||
43 | return $value; |
||
44 | } |
||
45 | |||
46 | return new DateTime($value); |
||
47 | } |
||
48 | |||
49 | /** |
||
50 | * Retain DateTime format for storage. |
||
51 | * |
||
52 | * @param \DateTime $value |
||
53 | * |
||
54 | * @return string |
||
55 | */ |
||
56 | public function fromDateTime($value) |
||
60 | |||
61 | /** |
||
62 | * Get a fresh timestamp for the model. |
||
63 | * |
||
64 | * @return \DateTime |
||
65 | */ |
||
66 | public function freshTimestamp() |
||
70 | |||
71 | /** |
||
72 | * Get a new query builder instance for the connection. |
||
73 | * |
||
74 | * @return Builder |
||
75 | */ |
||
76 | protected function newBaseQueryBuilder() |
||
77 | { |
||
78 | $connection = $this->getConnection(); |
||
79 | // Check the connection type |
||
80 | if ($connection instanceof \duxet\Rethinkdb\Connection) { |
||
81 | return new QueryBuilder($connection); |
||
82 | } |
||
83 | |||
84 | return parent::newBaseQueryBuilder(); |
||
85 | } |
||
86 | |||
87 | /** |
||
88 | * Create a new Eloquent query builder for the model. |
||
89 | * |
||
90 | * @param \duxet\Rethinkdb\Query\Builder $query |
||
91 | * |
||
92 | * @return \duxet\Rethinkdb\Eloquent\Builder|static |
||
93 | */ |
||
94 | public function newEloquentBuilder($query) |
||
98 | |||
99 | /** |
||
100 | * Define an inverse one-to-one or many relationship. |
||
101 | * |
||
102 | * @param string $related |
||
103 | * @param string $foreignKey |
||
104 | * @param string $otherKey |
||
105 | * @param string $relation |
||
106 | * |
||
107 | * @return \Illuminate\Database\Eloquent\Relations\BelongsTo |
||
108 | */ |
||
109 | public function belongsTo($related, $foreignKey = null, $otherKey = null, $relation = null) |
||
133 | |||
134 | /** |
||
135 | * Define a one-to-one relationship. |
||
136 | * |
||
137 | * @param string $related |
||
138 | * @param string $foreignKey |
||
139 | * @param string $localKey |
||
140 | * |
||
141 | * @return \Illuminate\Database\Eloquent\Relations\HasOne |
||
142 | */ |
||
143 | View Code Duplication | public function hasOne($related, $foreignKey = null, $localKey = null) |
|
151 | |||
152 | /** |
||
153 | * Define a one-to-many relationship. |
||
154 | * |
||
155 | * @param string $related |
||
156 | * @param string $foreignKey |
||
157 | * @param string $localKey |
||
158 | * |
||
159 | * @return \Illuminate\Database\Eloquent\Relations\HasMany |
||
160 | */ |
||
161 | View Code Duplication | public function hasMany($related, $foreignKey = null, $localKey = null) |
|
169 | } |
||
170 |
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.