php设计模式介绍之值对象模式第1/5页_php技巧

例如:通常用一个对象描述一个日期、一个数字或者货币。日期、整数或美元的类定义是都是便于使用的、快捷、便于封装的,并且方便进行拷贝,相互比较,甚至是创建。

从表面上看,这些描述简单的对象很容易被执行:它们的语句非常少,在构造类时无论是应用于Customer还是SKU都没有什么不同。这个想法似乎是正确的,但是所谓的"似乎正确"很容易产生一些bug。

请看下面的代码,这是一个关于以美元给员工发放工资的对象的定义和执行操作。多数情况下,它的运行是没有问题的。(这个类被命名为BadDollar,因为它还存在着bug)。考虑一下,看你是否能发现它的bug。

// 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());
}
那么, bug是什么呢?如果不能上面的代码例子中直观地发现问题,这里有个提示:雇员对象$p1和对象$p2使用着同一个BadDollar对象实例。

首先,类Work和类Person的实例已经创建。那么,假设每一个雇员最初有一个空的电子钱包,雇员的电子钱包Person:wallet是通过Work::payDay()函数返回的对象资源变量赋值的,所以被设定为一个BadDollar类的对象实例。

还记得PHP5的对象赋值处理方式吗?因为PHP5的对象赋值的处理方式,所以$job::salary,、$p1::wallet和$p2::wallet这三个看上去不同的对象实例虽然使用着不同的“标识符”,但是事实上,它们全部都指定到同一个对象实例。

因此,接下来的发放工资的操作(PayDay表示发放工资的日子,这里表示发放工资的动作),使用$job->payDay()本来仅仅是想增加$P1的工资,却出乎意料地次给$P2也发放了。并且,这个动作还改变了工作的基本工资的额度。因此,最后两个值的检测报错。

Value Object PHP5 Unit Test
1) Equal expectation fails because [Integer: 200] differs from [Float: 400] by 200
in testBadDollarWorking
in ValueObjTestCase
2) Equal expectation fails because [Integer: 200] differs from [Float: 400] by 200
in testBadDollarWorking
in ValueObjTestCase
FAILURES!!!

当前1/5页 12345下一页阅读全文

时间: 2024-10-26 00:58:12

php设计模式介绍之值对象模式第1/5页_php技巧的相关文章

php设计模式介绍之值对象模式

在所有的最简单的程序中,大多数对象都有一个标识,一个重要的商业应用对象,例如一个Customer 或者一个SKU,有一个或者更多的属性---id,name,email地址,这样可以把它从同一个类的其他实例区分 开来.此外,对象有一个恒定的标识:它是贯穿于整个应用程序的一个唯一的标识,对于程序员来说, "customer A"在任何地方就是"customer A",并且只要你的程序在持续运行时 "customer A"仍然是"custom

php设计模式介绍之编程惯用法第1/3页_php技巧

在这里总结的许多编程惯用法都是很值得做为单独一个章节的,甚至一本书的.你应该把这章做为PHP模式设计使用惯用法的相关介绍,而且查看一些列出的参考书来进行更深入的学习. 测试你的代码 可能没有什么代码惯用法比测试代码更加重要了.好的测试可以提高开发速度. 可能一开始,这句格言会和你的直觉相矛盾.你可能会断言,测试是自由的障碍物.事实上恰恰相反,如果你十分完整的运行那些测试来检查你的软件的公共接口,你就可能在不改变(或者更加糟糕,破坏)原来的应用软件的前提下改变自己系统内在的执行.测试并检验你的公共

php设计模式介绍之伪对象模式

面向对象的编程之所以丰富多彩,部分是由于对象间的相互联系与作用.一个单一的对象就能封装一 个复杂的子系统,使那些很复杂的操作能够通过一些方法的调用而简化.(无所不在的数据库连接就是 这样的一个对象实例.) 然而经常有这样的情况,对象间的交互性是如此复杂以至于我们不得 不面对类似"先有鸡还是先有蛋"这样伤脑筋的问题:如何创建并测试这样一个对象,他要 么依赖于很多已创建的对象,要么依赖于其他一些难以意识到的情况,如整个数据库的创建和测试. 问题 如何分隔并测试一个与其他对象和资源有关的代码

来源于WCF的设计模式:可扩展对象模式[上篇]

我一直很喜欢剖析微软一些产品.框架的底层实现.在我看来,这不但让我们可以更加深入地了解其运作的原理,同时也能提高设计/架构的技能.因为对于这些框架或者产品来说,高质量的设计是它们能够成功的一个最基本的因素.比如说比如ASP.NET,不但能够支持传统的Web Form应用,MVC同样建立在它基础之上.比如说WCF,从其诞生的那一天开始,真个架构体系就从未改变.这些应用在这些产品和框架上的设计其实是最值得我们学习的设计案例.比如说,今天我们介绍的"可扩展对象模式(Extensible Object

来源于WCF的设计模式:可扩展对象模式[下篇]

在<来源于WCF的设计模式:可扩展对象模式>我通过一个简单的例子介绍了基于IExtensibleObject<T>和IExtension<T>这两个接口为核心的"可扩展对象模式".在那篇文章中,我是通过编程的方式来应用扩展到扩展对象的.其实,如何能够通过配置的方式来定义扩展,这个所谓的"可扩展对象模式"将会发挥更大的威力.[源代码从这里下载] 目录: 一.将XxxBuilder定义在配置中 二.ExtensionConfigura

php设计模式介绍之装饰器模式

若你从事过面向对象的php开发,即使很短的时间或者仅仅通过本书了解了一些,你会知道,你可以 通过继承改变或者增加一个类的功能,这是所有面向对象语言的一个基本特性.如果已经存在的一个php 类缺少某些方法,或者须要给方法添加更多的功能(魅力),你也许会仅仅继承这个类来产生一个新类 -这建立在额外的代码上. 但是产生子类并不总是可能或是合适的.如果 你希望改变一 个已经初始化的对象的行为,你怎么办?或者,你希望继承许多类的行为,改怎么办?前一个,只能在于 运行时完成,后者显然时可能的,但是可能会导致

php设计模式 DAO(数据访问对象模式)

复制代码 代码如下: <?php /** * 数据访问对象(Data Access Object) 示例 * * @create_date: 2010-01-04 */ class BaseDAO { var $_db = null; var $_table = null; function BaseDAO($config) { $this->_db = new MysqlDB(); // 这里的不能进行操作 } /** * 获取处理 * * @param array $filter // 过

php设计模式 DAO(数据访问对象模式)_php技巧

复制代码 代码如下: <?php /** * 数据访问对象(Data Access Object) 示例 * * @create_date: 2010-01-04 */ class BaseDAO { var $_db = null; var $_table = null; function BaseDAO($config) { $this->_db = new MysqlDB(); // 这里的不能进行操作 } /** * 获取处理 * * @param array $filter // 过

创造世界上最简单的 PHP 开发模式第1/5页_php基础

/*************************************/ /* author:大龄青年 /* email :wenadmin@sina.com /* from: http://blog.csdn.net/hahawen /*************************************/ php 作为"最简单"的 Web 脚本语言, 在国内的市场越来越大,phper 越来越多,但是感觉大多数人好像没有考虑到模式问题,什么样的设计模式才是最优的,才是最适合