kind
1. Use less inheritance and more use of composition
##3. It is recommended to use final classes
1. Use less inheritance and more use of composition
As mentioned before in Design Patterns by the Gang of Four Say, we should try to give priority to composition rather than inheritance. There are many benefits to using both inheritance and composition. The main point of this guideline is that when you instinctively use inheritance, try to think about whether composition might better model your needs. In some cases, this is true. The next thing you may be thinking is, "So when should I use inheritance?" The answer depends on your question, but here are some instructions for when inheritance is better than composition: Your inheritance expresses the relationship of "is one" rather than "has one" (human->animal, user->user details) You can reuse the code of the base class (humans can be like animals Move)You want to make global changes to all derived classes by modifying the base class (modify the energy consumption of animals when they move)Bad:
class Employee { private $name; private $email; public function __construct(string $name, string $email) { $this->name = $name; $this->email = $email; } // ... } // 不好,因为 Employees "有" taxdata // 而 EmployeeTaxData 不是 Employee 类型的 class EmployeeTaxData extends Employee { private $ssn; private $salary; public function __construct(string $name, string $email, string $ssn, string $salary) { parent::__construct($name, $email); $this->ssn = $ssn; $this->salary = $salary; } // ... }
Good:
class EmployeeTaxData { private $ssn; private $salary; public function __construct(string $ssn, string $salary) { $this->ssn = $ssn; $this->salary = $salary; } // ... } class Employee { private $name; private $email; private $taxData; public function __construct(string $name, string $email) { $this->name = $name; $this->email = $email; } public function setTaxData(string $ssn, string $salary) { $this->taxData = new EmployeeTaxData($ssn, $salary); } // ... }
2. Avoid coherent interface
Continuous interfaceFluent interface is a An API design pattern designed to improve code readability in object-oriented programming. It is based on method chaining
Method chaining
mock
diff that leads to submission is not easy to read
Bad:
class Car { private $make = 'Honda'; private $model = 'Accord'; private $color = 'white'; public function setMake(string $make): self { $this->make = $make; // NOTE: Returning this for chaining return $this; } public function setModel(string $model): self { $this->model = $model; // NOTE: Returning this for chaining return $this; } public function setColor(string $color): self { $this->color = $color; // NOTE: Returning this for chaining return $this; } public function dump(): void { var_dump($this->make, $this->model, $this->color); } } $car = (new Car()) ->setColor('pink') ->setMake('Ford') ->setModel('F-150') ->dump();
Good:
class Car { private $make = 'Honda'; private $model = 'Accord'; private $color = 'white'; public function setMake(string $make): void { $this->make = $make; } public function setModel(string $model): void { $this->model = $model; } public function setColor(string $color): void { $this->color = $color; } public function dump(): void { var_dump($this->make, $this->model, $this->color); } } $car = new Car(); $car->setColor('pink'); $car->setMake('Ford'); $car->setModel('F-150'); $car->dump();
3. It is recommended to use final Class
Try to use final keywords when possible:
3. Encourage the single responsibility model.4. Encourage developers to use your public methods instead of obtaining access to protected methods through inherited classes.5. It is possible to modify the code without breaking the application that uses your class.The only condition is that your class should implement an interface and no other public methods are defined.For more informations you can read the blog post on this topic written by Marco Pivetta (Ocramius).bad:
final class Car { private $color; public function __construct($color) { $this->color = $color; } /** * @return string The color of the vehicle */ public function getColor() { return $this->color; } }good:
interface Vehicle { /** * @return string The color of the vehicle */ public function getColor(); } final class Car implements Vehicle { private $color; public function __construct($color) { $this->color = $color; } /** * {@inheritdoc} */ public function getColor() { return $this->color; } }