• 技术文章 >后端开发 >php教程

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

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

    从表面上看,这些描述简单的对象很容易被执行:它们的语句非常少,在构造类时无论是应用于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!!!
    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    上一篇:php REMOTE_ADDR之获取访客IP的代码_php技巧 下一篇:Gregarius中文日期格式问题解决办法_php技巧
    千万级数据并发解决方案

    相关文章推荐

    • 带你吃透16个PHP魔术方法• PHP 多进程 解决难题_php技巧• php smarty的预保留变量总结_php模板• [视频教程]PHP_LAMP兄弟连之PHP 9.4.文件系统处理• php在数据库抽象层简单使用PDO的方法_PHP
    1/1

    PHP中文网