对象和数据结构
对象和数据结构 Objects and Data Structures
1. 使用 getters 和 setters Use object encapsulation
1. 使用 getters 和 setters
在PHP中你可以对方法使用public
, protected
, private
来控制对象属性的变更。
-
当你想对对象属性做获取之外的操作时,你不需要在代码中去寻找并修改每一个该属性访问方法
-
当有
set
对应的属性方法时,易于增加参数的验证 -
封装内部的表示
-
使用
set
和get
时,易于增加日志和错误控制 -
继承当前类时,可以复写默认的方法功能
-
当对象属性是从远端服务器获取时,
get*
,set*
易于使用延迟加载
此外,这样的方式也符合OOP开发中的开闭原则
坏:
class BankAccount { public $balance = 1000; } $bankAccount = new BankAccount(); // Buy shoes... $bankAccount->balance -= 100;
好:
class BankAccount { private $balance; public function __construct(int $balance = 1000) { $this->balance = $balance; } public function withdraw(int $amount): void { if ($amount > $this->balance) { throw new \Exception('Amount greater than available balance.'); } $this->balance -= $amount; } public function deposit(int $amount): void { $this->balance += $amount; } public function getBalance(): int { return $this->balance; } } $bankAccount = new BankAccount(); // Buy shoes... $bankAccount->withdraw($shoesPrice); // Get balance $balance = $bankAccount->getBalance();
2. 给对象使用私有或受保护的成员变量
-
对public方法和属性进行修改非常危险,因为外部代码容易依赖他,而你没办法控制。对之修改影响所有这个类的使用者。 public methods and properties are most dangerous for changes, because some outside code may easily rely on them and you can't control what code relies on them. Modifications in class are dangerous for all users of class.
-
对protected的修改跟对public修改差不多危险,因为他们对子类可用,他俩的唯一区别就是可调用的位置不一样,对之修改影响所有集成这个类的地方。 protected modifier are as dangerous as public, because they are available in scope of any child class. This effectively means that difference between public and protected is only in access mechanism, but encapsulation guarantee remains the same. Modifications in class are dangerous for all descendant classes.
-
对private的修改保证了这部分代码只会影响当前类private modifier guarantees that code is dangerous to modify only in boundaries of single class (you are safe for modifications and you won't have Jenga effect).
所以,当你需要控制类里的代码可以被访问时才用public/protected
,其他时候都用private
。
可以读一读这篇 博客文章 ,Fabien Potencier写的.
坏:
class Employee { public $name; public function __construct(string $name) { $this->name = $name; } } $employee = new Employee('John Doe'); echo 'Employee name: '.$employee->name; // Employee name: John Doe
好:
class Employee { private $name; public function __construct(string $name) { $this->name = $name; } public function getName(): string { return $this->name; } } $employee = new Employee('John Doe'); echo 'Employee name: '.$employee->getName(); // Employee name: John Doe