博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PHP设计模式:值对象模式
阅读量:5146 次
发布时间:2019-06-13

本文共 2535 字,大约阅读时间需要 8 分钟。

值对象模式:

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

//值对象模式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;}$job = new Work;$p1 = new Person;$p2 = new Person;$p1->wallet = $job->payDay();//200$p1->wallet->add($job->payDay());//400$doller1 = $p1->wallet->getAmount();$p2->wallet = $job->payDay();print_r($p2->wallet->getAmount());//400$p2->wallet->add($job->payDay());$doller2 = $p2->wallet->getAmount();//800$p3->wallet = $job->payDay();//800$p3->wallet->add($job->payDay());$doller3 = $p3->wallet->getAmount();//1600echo $doller1."|".$doller2."|".$doller3;

  发放工资的操作(PayDay表示发放工资的日子,这里表示发放工资的动作),使用$job->payDay()本来仅仅是想增加$P1的工资,却出乎意料地次给$P2也发放了工资,导致了$p2初始工资变成了400。

 

做如下改动修复BUG:

值对象模式
//值对象模式class BadDollar {    protected $amount;    public function __construct($amount=0) {        $this->amount = (float)$amount;    }    public function getAmount() {        return $this->amount;    }    public function add($dollar) {        return new BadDollar($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;}$job = new Work;$p1 = new Person;$p2 = new Person;$p1->wallet = $job->payDay();//200$wallet1 = $p1->wallet->add($job->payDay());$doller1 = $wallet1->getAmount();//400$p2->wallet = $job->payDay();$wallet2 = $p2->wallet->add($job->payDay());$doller2 = $wallet2->getAmount();//400$p3->wallet = $job->payDay();$wallet3 = $p3->wallet->add($job->payDay());$doller3 = $wallet3->getAmount();//400echo $doller1."|".$doller2."|".$doller3;//400|400|400

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

对于值对象设计模式不变性是关键,任何对于一个Value Object的变量amount的改变,是通过创建一个新的带有不同预期值的类的实例来完成的

  1. 保护值对象的属性,禁止被直接访问。
  2. 在构造函数中就对属性进行赋值。
  3. 去掉任何一个会改变属性值的方式函数(setter),否则属性值很容易被改变。

 

转载于:https://www.cnblogs.com/colorstory/p/2716297.html

你可能感兴趣的文章
使用PHP拆分中文字符串的方法(收藏) 小节
查看>>
win10每次开机都显示“你的硬件设置已更改,请重启电脑……”的解决办法
查看>>
VMware环境和Window环境进行网络连接的问题
查看>>
macOS10.12允许所有来源设置
查看>>
C++有关 const & 内敛 & 友元&静态成员那些事
查看>>
函数积累
查看>>
python搜索引擎(转)
查看>>
关于height,line-height导致的样式混乱的问题
查看>>
《SEO实战密码》读后一点感受
查看>>
bzoj 4815 [Cqoi2017]小Q的表格——反演+分块
查看>>
Swift 入门之简单语法(六)
查看>>
shim和polyfill有什么区别
查看>>
Failed to load the JNI shared library “E:/2000/Java/JDK6/bin/..jre/bin/client/jvm.dll
查看>>
Zabbix3.4服务器的搭建--CentOS7
查看>>
〖Python〗-- IO多路复用
查看>>
栈(括号匹配)
查看>>
夜太美---酒不醉--人自醉
查看>>
Java学习 · 初识 面向对象深入一
查看>>
源代码如何管理
查看>>
vue怎么将一个组件引入另一个组件?
查看>>