gentil
1. Utilisez moins d'héritage et plus de combinaison
2 Évitez les interfaces cohérentes
3. Il est recommandé d'utiliser des classes finales
1. Tout comme le Gang of As mentionné précédemment dans Design Patterns by Four, nous devrions essayer de préférer la composition à l'héritage. L’utilisation à la fois de l’héritage et de la composition présente de nombreux avantages. Le point principal de cette ligne directrice est que lorsque vous utilisez instinctivement l’héritage, essayez de vous demander si la composition pourrait mieux modéliser vos besoins. Dans certains cas, cela est vrai.
La prochaine chose à laquelle vous pensez peut-être est : « Alors, quand dois-je utiliser l'héritage ? » La réponse dépend de votre question, mais voici quelques instructions pour savoir quand l'héritage est meilleur que la composition :
Votre héritage exprime « Oui » a. au lieu de "a une" relation (humain -> animal, utilisateur -> détails de l'utilisateur)
Vous pouvez réutiliser le code de la classe de base (les humains peuvent se déplacer comme des animaux)
Vous souhaitez modifier la classe de base pour toutes les classes dérivées faire des modifications globales (modifier la consommation énergétique des animaux lorsqu'ils bougent)
Mauvais : 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;
}
// ...
}
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. Eviter les interfaces fluides Interface continue Interface fluide
est un modèle de conception d'API conçu pour améliorer la lisibilité du code dans la programmation orientée objet. Il est basé sur le chaînage de méthodes Chaînage de méthodes
Là où il y a du contexte, la complexité du code peut être réduite, comme PHPUnit Mock Builder et Doctrine Query Builder, bien qu'il puisse y avoir certains contextes, souvent des objets de construction, où ce modèle réduit la verbosité du code (par exemple le PHPUnit Mock Builder ou le Doctrine Query Builder), le plus souvent cela a un certain prix :Fluent interface
是一种 旨在提高面向对象编程时代码可读性的API设计模式,他基于方法链Method chaining
有上下文的地方可以降低代码复杂度,例如PHPUnit Mock Builder 和Doctrine Query Builder ,更多的情况会带来较大代价:
While there can be some contexts, frequently builder objects, where this pattern reduces the verbosity of the code (for example the PHPUnit Mock Builder or the Doctrine Query Builder), more often it comes at some costs:
1. 破坏了 对象封装
2. 破坏了 装饰器模式
3. 在测试组件中不好做mock
4. 导致提交的diff
不好阅读
5. 了解更多请阅读 连贯接口为什么不好 ,作者 Marco Pivetta.
坏:
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();
好:
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. 推荐使用 final 类
能用时尽量使用 final
simulateur
dans le composant de test 4. Le diff
soumis est. pas facile à lire5. Pour en savoir plus, veuillez lire Pourquoi les interfaces cohérentes sont mauvaises, par Marco Pivetta.Mauvais:
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; } }
Bon:
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; } }
3 .Il est recommandé d'utiliser les classes finales
🎜Utilisez le mot-clé final
autant que possible : 🎜🎜1. Empêcher les chaînes d'héritage incontrôlées🎜🎜2. Encouragez les combinaisons.🎜🎜3. 🎜4. Encouragez les développeurs à utiliser vos méthodes publiques au lieu d'obtenir l'accès aux méthodes protégées via des classes héritées.🎜🎜5. Rendre possible l'utilisation de votre classe sans casser l'application La seule condition est que votre classe implémente une interface et aucune autre. les méthodes publiques sont définies.🎜🎜Pour plus d'informations, vous pouvez lire le billet de blog sur ce sujet écrit par Marco Pivetta (Ocramius 🎜🎜Mauvais:🎜rrreee🎜Bon:🎜rrreee🎜 🎜).