PHP 技巧 - 封裝基本的資料型別

心智極客發表於2019-12-23

對於一些基本資料型別 intstringbool 等,可以根據以下幾個規則來判斷是否要對其進行封裝。

封裝是否讓資訊更加的清晰 ?

示例

cache([], 50)

在該例子中,我們無法一眼就明確 50 代表的是秒、分鐘還是其他單位時間,因此,可以對其進行封裝

class Second {
    protected $seconds;
    public function __construct($seconds)
    {
        $this->seconds = $seconds;
    }
}

封裝後要表達的資訊將變得更加明確

function cache($data, Second $second)
{

}
cache([], new Second(50));

是否存在與屬性相關聯的行為 ?

例如,對於 weight(體重) 屬性而言,有著相關聯的行為,比如 gain(增加), gain 會導致 weight 的增加。通過封裝可以將屬性和行為進行關聯。

class Weight {
    protected $weight;
    public function __construct($weight)
    {
        $this->weight = $weight;
    }
    public function gain($pounds)
    {
        $this->weight += $pounds;
    }
    public function lose($pounds)
    {
        $this->weight -= $pounds;
    }
}

是否存在與屬性相關的驗證,來保持屬性的一致性 ?

將屬性進行封裝,可以對屬性的型別進行驗證,保持屬性的一致性。例如,郵箱地址這一屬性需要驗證郵箱的合法性

class EmailAddress {
    public function __construct($email)
    {
        if(! filter_var($email, FILTER_VALIDATE_EMAIL)){
            throw new InvalidArgumentException;
        }

        $this->email = $email;
    }
}

是否為重要的領域概念 ?

當屬性體現出具體的業務需求時,可以將其進行封裝。

class Location {
    public function __construct($latitude, $longtitude)
    {

    }
}

完整示例 - 健身相關業務封裝

體重

class Weight {
    protected $weight;
    public function __construct($weight)
    {
        $this->weight = $weight;
    }
    public function gain($pounds)
    {
        $this->weight += $pounds;
    }
    public function lose($pounds)
    {
        $this->weight -= $pounds;
    }
}

鍛鍊時長

class Timelength {
    protected $seconds;
    public function __construct($seconds)
    {
        $this->seconds = $seconds;
    }
    public static function fromMinutes($minutes)
    {
        return new static($minutes * 60);
    }
    public static function fromHours($hours)
    {
        return new static($hours * 60 * 60);
    }
    public function fromSeconds()
    {
        return $this->seconds;
    }
}

會員

class WorkoutPlaceMember {
    public function __construct($name, Weight $weight)
    {

    }
    public function workoutFor(Timelenght $lenght)
    {

    }
    public function workoutForHours($hour)
    {

    }
}

新增會員,錄入體重

$joe = new WorkoutPlaceMember('joe', new Weight(165));

記錄會員的鍛鍊時長

$joe->workoutFor(new Timelength(30));
$joe->workoutFor(Timelength::fromMinutes(34));

參考:

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章