使用getter和setter
在 PHP 中,通过为属性或方法设置 public, protected 和 private 关键字可以实现对属性或方法的可见性控制。不过,通过 getter 和 setter 也可以达到控制可见性的目的,并且在某些场景下它具备一些额外的好处。
使用 getter和 setter 有以下好处:
- 当你除了获取对象之外还想做一些别的事情时,就不用到项目中去查找所有的属性并修改
- 使添加验证更简单
- 在获取和设置时添加日志和错误处理更方便
- 我们可以延迟加载类的属性
- 继承了类,你可以重写默认的函数
另外,这是面向对象的基本设计原则中的开放/封闭原则。
Bad:
1 2 3 4 5 6 7 8 9
| class BankAccount { public $balance = 1000; }
$bankAccount = new BankAccount();
$bankAccount->balance -= 100;
|
Good:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| 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:
1 2 3 4 5 6 7 8 9 10 11 12
| class Employee { public $name;
public function __construct($name) { $this->name = $name; } }
$employee = new Employee('John Doe'); echo 'Employee name: '.$employee->name;
|
Good:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| 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();
|
使用组合而不是继承
这里不是说不使用继承,使用“组合模式”和使用“继承”都有很多好的理由。
这里想说的是当你本能的要使用继承时就想一想“组合模式”是否能更好帮你的解决问题。
那么,你可能想知道,“什么时候应该用继承?”, 这取决于你手头上问题。
以下几点说明了什么时候使用继承会更合适。
- 你的继承表达了一个对等(比如”人类是动物”)的关系,不是包含的关系(比如”用户具有用户详情”)
- 你能从基类中复用代码
- 你想通过修改全局类来对所有派生类进行修改。
Bad:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| 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); }
}
|