专注于WEB技术的IT博客

php值对象模式(二)

时间:2014-01-18分类: 设计模式浏览:1834
分享到:

让我们看看下一个例子:


      详细例子:


让我们在看一下更加复杂的例子中查看值对象模式的功能。让我们开始实现一个的基于PHP5中Dollar类中的一个Monopoly游戏。


第一个类Monopoly的框架如下:

class Monopoly {

protected $go_amount;

/**

* game constructor

* @return void

*/

public function __construct() {

$this->go_amount = new Dollar(200);

}

/**

* pay a player for passing 揋o�

* @param Player $player the player to pay

* @return void

*/

public function passGo($player) {

$player->collect($this->go_amount);

}

}

目前,Monopoly的功能比较简单。构造器创建一个Dollar类的实例$go_amount,设定为200,实例go_amount常常被passtGo()函数调用,它带着一个player参数,并让对象player的函数collect为player机上200美元.


Player类的声明请看下面代码,Monoplay类调用带一个Dollar参数的Player::collect()方法。然后把Dollar的数值加到Player的现金余额上。另外,通过判断Player::getBalance()方法函数返回来的余额,我们可以知道使访问当前Player和Monopoly对象实例是否在工作中。

class Player {

protected $name;

protected $savings;

/**

* constructor

* set name and initial balance

* @param string $name the players name

* @return void

*/

public function __construct($name) {

$this->name = $name;

$this->savings = new Dollar(1500);

}

/**

* receive a payment

* @param Dollar $amount the amount received

* @return void

*/

public function collect($amount) {

$this->savings = $this->savings->add($amount);

}

* return player balance

* @return float

*/

public function getBalance() {

return $this->savings->getAmount();

}

}

上边已经给出了一个Monopoly和Player类,你现在可以根据目前声明的几个类定义进行一些测试了。

MonopolyTestCase的一个测试实例可以像下面这样写:

class MonopolyTestCase extends UnitTestCase {

function TestGame() {

$game = new Monopoly;

$player1 = new Player(‘Jason’);

$this->assertEqual(1500, $player1->getBalance());

$game->passGo($player1);

$this->assertEqual(1700, $player1->getBalance());

$game->passGo($player1);

$this->assertEqual(1900, $player1->getBalance());

}

}

如果你运行MonopolyTestCase这个测试代码,代码的运行是没有问题的。现在可以添加一些新的功能。


另一个重要的概念是对象Monopoly中的租金支付。让我们首先写一个测试实例(测试引导开发)。下面的代码希望用来实现既定的目标。

function TestRent() {

$game = new Monopoly;

$player1 = new Player(‘Madeline’);

$player2 = new Player(‘Caleb’);

$this->assertEqual(1500, $player1->getBalance());

$this->assertEqual(1500, $player2->getBalance());

$game->payRent($player1, $player2, new Dollar(26));

$this->assertEqual(1474, $player1->getBalance());

$this->assertEqual(1526, $player2->getBalance());

}

 根据这个测试代码,我们需要在Monopoly对象中增加payRent()的方法函数来实现一个Player对象去支付租金给另一个Player对象.

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));

}

}

 payRent()方法函数实现了两个player对象之间($from和$to)的租金支付。方法函数Player::collect()已经被定义了,但是Player::pay()必须被添加进去,以便实例$from通过pay()方法支付一定的Dollar数额$to对象中。首先我们定义Player::pay()为:

class Player {

// ...

public function pay($amount) {

$this->savings = $this->savings->add(-1 * $amount);

}

}

但是,我们发现在PHP中你不能用一个数字乘以一个对象(不像其他语言,PHP不允许重载操作符,以便构造函数进行运算)。所以,我们通过添加一个debit()方法函数实现Dollar对象的减的操作。

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());

}

}

引入Dollar::debit()后,Player::pay()函数的操作依然是很简单的。

class Player {

// ...

/**

* make a payment

* @param Dollar $amount the amount to pay

* @return Dollar the amount payed

*/

public function pay($amount) {

$this->savings = $this->savings->debit($amount);

return $amount;

}

}

 Player::pay()方法返回支付金额的$amount对象,所以Monopoly::payRent()中的语句$to->collect($from->pay($rent))的用法是没有问题的。这样做的话,如果将来你添加新的“商业逻辑”用来限制一个player不能支付比他现有的余额还多得金额。(在这种情况下,将返回与player的账户余额相同的数值。同时,也可以调用一个“破产异常处理”来计算不足的金额,并进行相关处理。对象$to仍然从对象$from中取得$from能够给予的金额。)


注:术语------商业逻辑


在一个游戏平台的例子上提及的“商业逻辑”似乎无法理解。这里的商业的意思并不是指正常公司的商业运作,而是指因为特殊应用领域需要的概念。请把它认知为 “一个直接的任务或目标”,而不是“这里面存在的商业操作”。


所以,既然目前我们讨论的是一个Monopoly,那么这里的 “商业逻辑”蕴含的意思就是针对一个游戏的规则而说的。(待续)


本文由Phpchina翻译,作者 Christopher Alexander 

猜你喜欢
php值对象模式(三)
php值对象模式(一)
php设计模式导言
标签 : php 设计模式
除非注明,本文首发网志博客,欢迎转载!转载请注明本文地址:http://w3note.com/web/138.html,谢谢。
  • 评论
  • 赞助本站