刚看完,也许还没有理解透彻
5月16号,感受最深刻的是,这一章主要阐述PHP4与PHP5在对象引用时候值,是否改变。
// PHP5
class BadDollar {
protected $amount;
public function __construct($amount=0) {
$this->amount = (float)$amount;
}
public function getAmount() {
return $this->amount;
}
public function add($dollar) {
$this->amount += $dollar->getAmount();
}
}
class Work {
protected $salary;
public function __construct() {
$this->salary = new BadDollar(200);
}
public function payDay() {
return $this->salary;
}
}
class Person {
public $wallet;
}
function testBadDollarWorking() {
$job = new Work;
$p1 = new Person;
$p2 = new Person;
$p1->wallet = $job->payDay();
$this->assertEqual(200, $p1->wallet->getAmount());
$p2->wallet = $job->payDay();
$this->assertEqual(200, $p2->wallet->getAmount());
$p1->wallet->add($job->payDay());
$this->assertEqual(400, $p1->wallet->getAmount());
//this is bad — actually 400
$this->assertEqual(200, $p2->wallet->getAmount());
//this is really bad — actually 400
$this->assertEqual(200, $job->payDay()->getAmount());
}
-------------------------------------解决方案------------------------------
class Dollar {
protected $amount;
public function __construct($amount=0) {
$this->amount = (float)$amount;
}
public function getAmount() {
return $this->amount;
}
public function add($dollar) {
$this->amount = new Doller ($this->amount +$dollar->getAmount() );
}
}
因为,php5‘ 对象句柄’的概念,其实p1,与p2 使用的是同一个对象,即p1工资+200后,其实p2也增加200,这与原先的预期不想符合。
简单来说,在PHP5 里面使用价值设计模式时,需要注意以下几个方面:
1.保护值对象的属性,禁止被直接访问。
2.在构造函数中就对属性进行赋值。
3.去掉任何一个会改变属性值的方式函数(setter),否则属性值很容易被改变。
假如你回想一下这本书序言中的“对象句柄”部分,它提出了三个 “规则” ,当你在
PHP4 中使用对象去模仿PHP5 中的对象句柄时,这三个规则总是适用的:
1. 通过指针($obj=&new class;)来创建对象。
2. 用指针(function funct(&$obj) param{})来传递对象。
3. 用指针(function &some_funct() {} $returned_obj =& some_funct())来获取一个对象。
在所有PHP4 对象中,私有变量的前缀使用一个下划线,但是你还是可以
从外部来直接访问私有属性和方法函数。