PHP代碼簡潔之道——類和對象部分

使用getter和setter

在 PHP 中,經過爲屬性或方法設置 public, protected 和 private 關鍵字能夠實現對屬性或方法的可見性控制。不過,經過 getter 和 setter 也能夠達到控制可見性的目的,而且在某些場景下它具有一些額外的好處。php

使用 getter和 setter 有如下好處:函數

  • 當你除了獲取對象以外還想作一些別的事情時,就不用到項目中去查找全部的屬性並修改
  • 使添加驗證更簡單
  • 在獲取和設置時添加日誌和錯誤處理更方便
  • 咱們能夠延遲加載類的屬性
  • 繼承了類,你能夠重寫默認的函數

另外,這是面向對象的基本設計原則中的開放/封閉原則。this

Bad:設計

class BankAccount
{
    public $balance = 1000;
}

$bankAccount = new BankAccount();

// 買了一雙鞋...
$bankAccount->balance -= 100;

Good:日誌

class BankAccount
{
    private $balance;

    public function __construct($balance = 1000)
    {
      $this->balance = $balance;
    }
    
    //作一些事情
    public function withdrawBalance($amount)
    {
        if ($amount > $this->balance) {
            throw new \Exception('Amount greater than available balance.');
        }

        $this->balance -= $amount;
    }

    public function depositBalance($amount)
    {
        $this->balance += $amount;
    }

    public function getBalance()
    {
        return $this->balance;
    }
}

$bankAccount = new BankAccount();

// 買了一雙鞋...
$bankAccount->withdrawBalance($shoesPrice);

// 獲取結餘
$balance = $bankAccount->getBalance();

讓對象具備私有或受保護的的成員

Bad:code

class Employee
{
    public $name;

    public function __construct($name)
    {
        $this->name = $name;
    }
}

$employee = new Employee('John Doe');
echo 'Employee name: '.$employee->name; // Employee name: John Doe

Good:對象

class Employee
{
    private $name;

    public function __construct($name)
    {
        $this->name = $name;
    }

    public function getName()
    {
        return $this->name;
    }
}

$employee = new Employee('John Doe');
echo 'Employee name: '.$employee->getName(); // Employee name: John Doe

使用組合而不是繼承

這裏不是說不使用繼承,使用「組合模式」和使用「繼承」都有不少好的理由。繼承

這裏想說的是當你本能的要使用繼承時就想想「組合模式」是否能更好幫你的解決問題。get

那麼,你可能想知道,「何時應該用繼承?」, 這取決於你手頭上問題。it

如下幾點說明了何時使用繼承會更合適。

  • 你的繼承表達了一個對等(好比"人類是動物")的關係,不是包含的關係(好比"用戶具備用戶詳情")
  • 你能從基類中複用代碼
  • 你想經過修改全局類來對全部派生類進行修改。

Bad:

class Employee 
{
    private $name;
    private $email;

    public function __construct($name, $email)
    {
        $this->name = $name;
        $this->email = $email;
    }

    // ...
}

// 由於僱員和稅收不是對等關係而是包含的關係
// 因此這裏應用組合比較合適


class EmployeeTaxData extends Employee 
{
    private $ssn;
    private $salary;
    
    public function __construct($name, $email, $ssn, $salary)
    {
        parent::__construct($name, $email);

        $this->ssn = $ssn;
        $this->salary = $salary;
    }

    // ...
}

Good:

class EmployeeTaxData 
{
    private $ssn;
    private $salary;

    public function __construct($ssn, $salary)
    {
        $this->ssn = $ssn;
        $this->salary = $salary;
    }

    // ...
}

class Employee 
{
    private $name;
    private $email;
    private $taxData;

    public function __construct($name, $email)
    {
        $this->name = $name;
        $this->email = $email;
    }

    public function setTaxData($ssn, $salary)
    {
        $this->taxData = new EmployeeTaxData($ssn, $salary);
    }

    // ...
}
相關文章
相關標籤/搜索