對於一些基本資料型別 int
、string
、bool
等,可以根據以下幾個規則來判斷是否要對其進行封裝。
封裝是否讓資訊更加的清晰 ?
示例
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 協議》,轉載必須註明作者和本文連結