I found a book from 2005 on php design patterns at the office and had a look at it. The book presents solution both for php 4 and 5.
The first presented pattern was called Object value pattern, and the presented code has been bugging me since I read it. Did I missunderstand something, or was this an issue due to lack of access modifiers in php 4?
I wrote some code which ought to show the concept, the book's presented solution and the way I'd go. If something seems strange in all this, I could of course present code identical to that found in the book but with other class, function and variable names to get around copy right issues. Just let me know in that case.
Original code. The problem is that those two people share the same wallet. The public access is a problem in my books, while them sharing one wallet isn't necessarily a problem.
class Wallet {
private $cash;
public function __construct($cash = 0) {
$this->cash = $cash;
}
public function add($cash) {
$this->cash += $cash;
}
public function getCash() {
return $this->cash;
}
}
class Person {
public $wallet;
public function payDay($amount) {
$this->wallet->add($amount);
}
public function getCash() {
return $this->wallet->getCash();
}
}
$w = new Wallet();
$p1 = new Person();
$p1->wallet = $w;
$p2 = new Person();
$p2->wallet = $w;
$p1->payDay(200);
echo $p1->getCash()."\n";
$p2->payDay(200);
echo $p2->getCash()."\n";
echo $p1->getCash()."\n";
Book's presented solution
class Wallet {
private $cash;
public function __construct($cash = 0) {
$this->cash = $cash;
}
// Seriously? This seems messed up to me...
public function add($cash) {
$w = new Wallet($cash + $this->cash);
return $w;
}
public function getCash() {
return $this->cash;
}
}
class Person {
public $wallet;
public function payDay($amount) {
$this->wallet = $this->wallet->add($amount);
}
public function getCash() {
return $this->wallet->getCash();
}
}
$w = new Wallet();
$p1 = new Person();
$p1->wallet = $w;
$p2 = new Person();
$p2->wallet = $w;
$p1->payDay(200);
echo $p1->getCash()."\n";
$p2->payDay(200);
echo $p2->getCash()."\n";
echo $p1->getCash()."\n";
My preferred approach
// My approach
class Wallet {
private $cash;
public function __construct($cash = 0) {
$this->cash = $cash;
}
public function add($cash) {
$this->cash += $cash;
}
public function getCash() {
return $this->cash;
}
}
class Person {
private $wallet;
public function __construct() {
$this->wallet = new Wallet();
}
public function payDay($amount) {
$this->wallet->add($amount);
}
public function getCash() {
return $this->wallet->getCash();
}
}
$w = new Wallet();
$p1 = new Person();
$p2 = new Person();
$p1->payDay(200);
echo $p1->getCash()."\n";
$p2->payDay(200);
echo $p2->getCash()."\n";
echo $p1->getCash()."\n";
Additionally, you might want to actually let people share the same wallet, bank account or whatever. And what would be the best way to deal with wallet sharing? Something like this?
class Person {
// ... as before
public function shareWalletWith($person) {
$person->acceptWallet($this->wallet);
}
public function acceptWallet($wallet) {
$this->wallet = $wallet;
}
}