親切
1. 継承を減らし、合成をより多く使用します
前に説明したように、 Gang of Four によるデザイン パターン 継承ではなく合成を優先するように努めるべきだと言えます。継承と合成の両方を使用すると、多くの利点があります。このガイドラインの主なポイントは、直感的に継承を使用するときに、合成がニーズをより適切にモデル化できるかどうかを考えてみることです。場合によっては、これは真実です。 次に考えられるのは、「では、いつ継承を使用すればよいのでしょうか?」ということです。答えは質問によって異なりますが、継承が合成よりも優れている場合の手順をいくつか示します。 継承は、「ある」ではなく「ある」という関係を表します (人間 -> 動物、ユーザー -> ユーザーの詳細) 基本クラスのコードを再利用できます (人間は動物に似ることができます) )基本クラスを変更して、すべての派生クラスにグローバルな変更を加えたいと考えています (動物が移動するときのエネルギー消費を変更します)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. 一貫性のあるインターフェースを避ける
継続的インターフェース流暢なインターフェースは API ですオブジェクト指向プログラミングにおけるコードの可読性を向上させるために設計されたデザイン パターン。これはメソッド チェーンに基づいています
メソッド チェーン
モック
diff は読みにくいです
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. を使用することをお勧めします。 Final クラス
可能な場合は Final を使用するようにしてください。キーワード:
3. 単一責任モデルを奨励します。4. 継承されたクラスを通じて保護されたメソッドにアクセスする代わりに、パブリック メソッドを使用するよう開発者に奨励します。5.クラスを使用するアプリケーションを中断することなくコードを作成できます。唯一の条件は、クラスがインターフェイスを実装し、他のパブリック メソッドが定義されていないことです。詳細については、ブログ投稿を参照してください。このトピックについては、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; } }