设计模式 一 值对象模式(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,或者不利于团队开发,不利于二次开发,不利于修改,下一个模式,最重要的模式之一,工厂模式,我继续写
相关文章推荐
- 【设计模式】传输对象模式(Transfer Object Pattern)
- 设计模式之空对象模式--- Pattern Null Object
- 设计模式学习—传输对象模式(Transfer Object Design Pattern)
- 设计模式【空对象模式NullObjectPattern】
- [置顶] 设计模式之单例模式 (Design patterns of the The singleton pattern)c#
- 重构改善既有代码设计--重构手法19:Replace Data Value with Object (以对象取代数据值)
- 被遗忘的设计模式——空对象模式(Null Object Pattern)
- 设计模式之单例模式 (Design patterns of the The singleton pattern)c#
- Active Object -An Object Behavioral Pattern for Concurrent Programming 主动对象模式 (转)
- 设计模式:空对象模式(Null Object Pattern)
- 7.5.1.2 装饰设计模式(THE DECORATOR DESIGN PATTERN)
- 主动对象模式(Active Object pattern)
- 面向对象设计模式之---建造者模式(Builder Pattern)
- 设计模式之美:Type Object(类型对象)
- 类对象工厂设计模式(Factory Pattern)
- 设计模式之美:Role Object(角色对象)
- 设计模式(一)The Strategy Pattern 策略模式
- 设计模式之 观察者模式 the observer design pattern ---------《head first design pattern》
- 主动对象模式(Active Object pattern)
- 设计模式学习—数据访问对象模式(Data Access Object Design Pattern)