類別
1. 少用繼承多用組合
正如the Gang of Four 所著的設計模式之前所說, 我們應該盡量優先選擇組合而不是繼承的方式。使用繼承和組合都有許多好處。這個準則的主要意義在於當你本能的使用繼承時,試著思考一下組合是否能更好地對你的需求建模。在一些情況下,是這樣的。 接下來你或許會想,「那我應該在什麼時候使用繼承?」 答案依賴於你的問題,當然下面有一些何時繼承比組合更好的說明:你的繼承表達了“是一個”而不是“有一個”的關係(人類-”動物,用戶-”用戶詳情)你可以復用基類的代碼(人類可以像動物一樣移動)你想透過修改基底類別對所有衍生類別做全域的修改(當動物移動時,修改她們的能量消耗)壞:
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. 避免連貫介面
連貫介面Fluent interface#是一種旨在提高物件導向程式設計時程式碼可讀性的API設計模式,他基於方法鏈
Method chaining
mock
diff不好閱讀
壞:
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 關鍵字:
3. 鼓勵單一職責模式.4. 鼓勵開發者用你的公開方法而非透過繼承類別來取得受保護方法的存取權.5. 使得在不破壞使用你的類別的應用程式的情況下修改程式碼成為可能.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).壞:
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; } }好:
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; } }