您的位置:首页 > 移动开发 > Objective-C

设计模式 一 值对象模式(The Value Object Pattern)

2012-03-08 14:43 543 查看
TestRent();

function TestRent() {
$game = new Monopoly;
$player1 = new Player('Madeline', 1000);
$player2 = new Player('Caleb', 1500);

$game->payRent($player1, $player2, new Dollar(20));
echo $player1->getBalance();
echo $player2->getBalance();
}

class Monopoly {
/**
* pay rent from one player to another
* @param Player $from the player paying rent
* @param Player $to the player collecting rent
* @param Dollar $rent the amount of the rent
* @return void
*/
public function payRent($from, $to, $rent) {
$to->collect($from->pay($rent));
}
}

class Player {
protected $name;
protected $savings;

public function __construct($name, $dollar = 1500) {
$this->name = $name;
$this->savings = new Dollar($dollar);
}

public function collect($amount) {
$this->savings = $this->savings->add($amount);
}

public function pay($amount) {
$this->savings = $this->savings->debit($amount);
return $amount;
}

public function getBalance() {
return $this->savings->getAmount();
}
}

class Dollar {

protected $amount;
public function __construct($amount=0) {
$this->amount = (float)$amount;
}

public function getAmount() {
return $this->amount;
}

public function add($dollar) {
return new Dollar($this->amount + $dollar->getAmount());
}

public function debit($dollar) {

return new Dollar($this->amount - $dollar->getAmount());
}
}


值对象模式
大意理解是,如果代码写的不正确,程序会改变一些不希望改变的值,并造成错误,在例子中,有说明一个存在bug的程序....并做出解释....其实我在思考那个程序......后面写了一个Person的类,用这个类调用BadDollar 类和Work类的一些东西,person被实例化了两次...其实...person这个类里面并没有任何的方法,所以无论对它实例化n次,都对前面两个类不起作用,所以当然得到的值,会看上去相互影响了...其实我觉得这个和person这个类 是没有任何关系的...

实例化person后,希望只修改p1的工资,结果却对p2起了作用,原因是在第一次实例化p1的时间,就改变了值,自然p2的值也被修改了,得到了不想要的结果.那么,不喜欢那个值发生变化,是否可以使用私有的属性呢,保证这个变量不会被外界所影响,但是又可以通过其他方式访问....我要再想一想.....

我的解决办法是,分别对work这个类做实例化,$job = new work; $job1 = new work; 然后用person去访问不同的实例化后的work 这样就不会产生相互影响了

我看看作者是用的什么办法...

作者的方法当然比我高明的多,代码如下(作者有用他自己的一个架构,我这里没有)

<?

class Dollar{

protected $amount;

function __construct($amount=0){

$this->amount = $amount;

}

function getAmount(){

return $this->amount;

}

function add($dollar){

return new Dollar($this->amount+$dollar);

}

}

$a = new Dollar;

$a->add(200);

$a->add(400);

print_r($a->add(200));

print_r($a->add(400));

?>

得出的结果,是并没有相互影响,只是有点不明白为什么返回的书数组

作者对代码解释如下

在这种情况下,虽然没有设定函数Dollar::amount(),但在对象的实例化期时,参数Dollar::amount就已经被赋值了。而函数Dollar::getAmount()只是提供一个访问Dollar属性的功能,在这里访问的数据类型为浮点型。

最有趣的变化是在Dollar::add()方法函数中。并不是直接改变$this->amount变量的值从而会改变已存在的Dollar对象实例,而是创建并返回一个新的Dollar实例。现在,尽管你指定当前对象给多个变量,但是每一个变量的变化都不会影响其它的变量实例。

对于价值设计模式不变性是关键,任何对于一个Value Object的变量amount的改变,是通过创建一个新的带有不同预期值的类的实例来完成的。上文中提高的最初那个$this->amount变量的值从未改变。

简单来说,在PHP5里面使用价值设计模式时,需要注意以下几个方面:
1.保护值对象的属性,禁止被直接访问。
2.在构造函数中就对属性进行赋值。
3.去掉任何一个会改变属性值的方式函数(setter),否则属性值很容易被改变。
以上三步创建了一个不变的值,这个值一旦被初始化设置之后就不能被改变。当然,你也应该提供一个查看函数或者是访问Value Object的属性的方法,并且可以添加一些与这个类相关的函数。值对象并不是只能用在一个简单的架构上,它也可以实现重要的商务逻辑应用。
我再认真读一下,再写心得
认真看了下,作者说:通过创建一个新的带有不同预期值的类的实例来完成的,嗯....高明的地方就是在创建的时候,就把自己实例化了,所以$a->add(200);$a->add(400);一样得到的是两个实例化后的结果,并无相互影响。
保证值对象模式的关键作者也说了
设置private 或者protected保证初始值不被外界访问方式修改(protected 继承的时候能修改)
利用构造函数对属性的修改赋值 其意义也是如此 不希望被外界修改
去掉改变值属性的函数 其实三点说的都是一个东西,保证值不被修改
总重要的地方 是不是应该是对对象的不同实例化,就如作者这样呢?
今天在周兄的提示下,进一步思考值对象模式,以下是进一步的理解
所谓值对象模式,从字面意思就好理解,以前我们使用的都是传递的值,把得到的值进行传递,现在我们用的方式是把对象作为值来传递,传递的是对象,不是值,这样我们就把值隐藏起来了,保证不被外界访问或者破坏,你要得到这个值也行啊,用我提供的方式去得到吧,但是外界不可以修改.....
我想这个就是值对象模式的好处吧
php的若干设计模式,其实就是面向对象方式的一些优秀的写法,如果只是凭借想像写一些代码,可能会造成很多隐藏起来的问题,可能会有很多隐藏的bug,或者不利于团队开发,不利于二次开发,不利于修改,下一个模式,最重要的模式之一,工厂模式,我继续写
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: