## 对象和数据结构
### 使用 getters 和 setters
在PHP中你可以对方法使用`public`, `protected`, `private` 来控制对象属性的变更。
* 当你想对对象属性做获取之外的操作时,你不需要在代码中去寻找并修改每一个该属性访问方法
* 当有`set`对应的属性方法时,易于增加参数的验证
* 封装内部的表示
* 使用set*和get*时,易于增加日志和错误控制
* 继承当前类时,可以复写默认的方法功能
* 当对象属性是从远端服务器获取时,`get`、`set`易于使用延迟加载
此外,这样的方式也符合OOP开发中的[开闭原则](https://segmentfault.com/a/1190000013123183)
**差:**
```php
class BankAccount
{
public $balance = 1000;
}
$bankAccount = new BankAccount();
// Buy shoes...
$bankAccount->balance -= 100;
```
**优:**
```php
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();
```
### 对象属性多使用private/protected限定
* 对`public`方法和属性进行修改非常危险,因为外部代码容易依赖他,而你没办法控制。**对之修改影响所有这个类的使用者。
* 对`protected`的修改跟对`public`修改差不多危险,因为他们对子类可用,他俩的唯一区别就是可调用的位置不一样,**对应修改影响所有使用这个类的地方。
* 对`private`的修改保证了这部分代码**只会影响当前类。
当需要控制类里的代码可以被访问时才用`public/protected`,其他时候都用`private`。
**差:**
```php
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
```
**优:**
```php
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
```