亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

1. 少用繼承多用組合

2. 避免連貫接口

3. 推薦使用 final 類

1. 少用繼承多用組合

正如 the Gang of Four 所著的設(shè)計(jì)模式之前所說, 我們應(yīng)該盡量?jī)?yōu)先選擇組合而不是繼承的方式。使用繼承和組合都有很多好處。 這個(gè)準(zhǔn)則的主要意義在于當(dāng)你本能的使用繼承時(shí),試著思考一下組合是否能更好對(duì)你的需求建模。 在一些情況下,是這樣的。

接下來你或許會(huì)想,“那我應(yīng)該在什么時(shí)候使用繼承?” 答案依賴于你的問題,當(dāng)然下面有一些何時(shí)繼承比組合更好的說明:

你的繼承表達(dá)了“是一個(gè)”而不是“有一個(gè)”的關(guān)系(人類-》動(dòng)物,用戶-》用戶詳情)

你可以復(fù)用基類的代碼(人類可以像動(dòng)物一樣移動(dòng))

你想通過修改基類對(duì)所有派生類做全局的修改(當(dāng)動(dòng)物移動(dòng)時(shí),修改她們的能量消耗)

壞:

 class Employee
{
    private $name;
    private $email;
 
    public function __construct(string $name, string $email)
    {
        $this->name = $name;
        $this->email = $email;
    }
 
    // ...
}
 
 
// 不好,因?yàn)?nbsp;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是一種 旨在提高面向?qū)ο缶幊虝r(shí)代碼可讀性的API設(shè)計(jì)模式,他基于方法鏈Method chaining

有上下文的地方可以降低代碼復(fù)雜度,例如PHPUnit Mock Builder 和Doctrine Query Builder ,更多的情況會(huì)帶來較大代價(jià):

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. 破壞了 對(duì)象封裝

2. 破壞了 裝飾器模式

3. 在測(cè)試組件中不好做mock

4. 導(dǎo)致提交的diff不好閱讀

5. 了解更多請(qǐng)閱讀 連貫接口為什么不好 ,作者 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 類

能用時(shí)盡量使用 final 關(guān)鍵字:

1. 阻止不受控的繼承鏈

2. 鼓勵(lì) 組合.

3. 鼓勵(lì) 單一職責(zé)模式.

4. 鼓勵(lì)開發(fā)者用你的公開方法而非通過繼承類獲取受保護(hù)方法的訪問權(quán)限.

5. 使得在不破壞使用你的類的應(yīng)用的情況下修改代碼成為可能.

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;
    }
}