In all of the simplest programs, most objects have an identifier, an important commercial application object, such as a customer or a SKU, with one or more attributes---id,name,email address, so that it can be distinguished from other instances of the same class. In addition, the object has a constant identity: it is a unique identity throughout the application, and for programmers, "customer a" is "customer a" anywhere, and "customer a" is still "customer a" as long as your program is running continuously. "。 But an object does not need to have an identity. Some objects are only intended to describe the properties of other objects.
For example, an object is usually used to describe a date, a number, or a currency. Class definitions for dates, integers, or dollars are all easy to use, fast, easy to encapsulate, and easy to copy, compare, or even create.
On the surface, these simple objects are easy to execute: They have very few statements and are no different when constructing a class, whether it is applied to a customer or a SKU. The idea seems to be correct, but the so-called "seems right" can easily produce some bugs.
Take a look at the code below, which is the definition and execution of an object that pays employees in dollars. In most cases, it's not a problem to run. (This class is named Baddollar because it still has bugs). Think about it and see if you can find the 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;p ublic function __construct () {
$this->salary = new Baddollar (200);}
Public Function PayDay () {
return $this->salary;
}
}
Class Person {
Public $wallet;
}
function testbaddollarworking () {
$job = new Work;
$p 1 = new person;
$p 2 = new person;
$p 1->wallet = $job->payday ();
$this->assertequal ($p 1->wallet->getamount ());
$p 2->wallet = $job->payday ();
$this->assertequal ($p 2->wallet->getamount ());
$p 1->wallet->add ($job->payday ());
$this->assertequal ($p 1->wallet->getamount ());
This is bad-actually 400
$this->assertequal ($p 2->wallet->getamount ());
This is really bad-actually 400
$this->assertequal ($job->payday ())->getamount ());
}
So, what is a bug? If you can't visually spot the problem in the above code example, here's a hint: the Employee object $p1 and object $p2 use the same Baddollar object instance.
First, instances of class work and class person have been created. So, assuming that each employee initially has an empty electronic wallet, the employee's electronic wallet Person:wallet is assigned to the object resource variable returned by the work::p Ayday () function, so it is set as an object instance of a Baddollar class.
Remember the PHP5 object assignment approach? Because of the way PHP5 objects are assigned, $job::salary, $p 1::wallet and $p2::wallet these three seemingly different object instances use different identifiers, but in fact they are all assigned to the same object instance.
As a result, the next wage-issuing operation (PayDay said the day of the pay, here is the act of paying wages), the use of $job->payday () was only to increase the $p1 wages, but unexpectedly to $P2 also issued. Also, this action changes the amount of base pay for the job. Therefore, the last two values were detected with an error.
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!!!