-
-
Save ryross/4119149 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
interface Context { | |
public function execute($params); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class Data | |
{ | |
private $roles = array(); | |
private $method_map = array(); | |
public function extend($class) | |
{ | |
$role = new $class($this); | |
$this->roles[$class] = $role; | |
foreach(get_class_methods($class) as $method) | |
{ | |
$this->method_map[$method] = $role; | |
} | |
} | |
public function unextend($class) | |
{ | |
$role = $this->roles[$class]; | |
unset($this->roles[$class]); | |
$this->method_map = array_filter( | |
$this->method_map, | |
function($stored_role) use($role){ | |
return $stored_role !== $role; | |
}); | |
} | |
public function __call($method, $args) | |
{ | |
if(! array_key_exists($method, $this->method_map)) { | |
throw new Exception("Method $method doesn't exist on this object"); | |
} | |
return call_user_func_array( | |
array($this->method_map[$method], $method), $args | |
); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class Role | |
{ | |
private $data; | |
public function __construct($data) | |
{ | |
$this->data = $data; | |
} | |
public function __get($property) | |
{ | |
return $this->data->$property; | |
} | |
public function __set($property, $value) | |
{ | |
$this->data->$property = $value; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
require('DCI_Data.php'); | |
require('DCI_Role.php'); | |
require('DCI_Context.php'); | |
class Account extends Data { | |
public $balance = 0; | |
} | |
class MoneySource extends Role | |
{ | |
public function withdraw($amount) | |
{ | |
if ($amount <= $this->balance) | |
{ | |
$this->balance -= $amount; | |
return $amount; | |
} | |
else | |
{ | |
throw new Exception("Insufficient Funds\n". "Tried to withdraw $amount. {$this->balance} available."); | |
} | |
} | |
} | |
class MoneyDestination extends Role | |
{ | |
public function deposit($amount) | |
{ | |
$this->balance += $amount; | |
} | |
} | |
class Transfer implements Context | |
{ | |
private $_source; | |
private $_destination; | |
private $_amount; | |
public function __construct(Account $source, Account $destination, $amount = 0) | |
{ | |
$this->_source = $source; | |
$this->_source->extend('MoneySource'); | |
$this->_destination = $destination; | |
$this->_destination->extend('MoneyDestination'); | |
$this->_amount = $amount; | |
} | |
public function execute($params = array()) | |
{ | |
$withdrawn = $this->_source->withdraw($this->_amount); | |
if ($withdrawn) | |
{ | |
$this->_destination->deposit($this->_amount); | |
} | |
} | |
} | |
$source_account = new Account(); | |
$source_account->balance = 20; | |
$destination_account = new Account(); | |
$destination_account->balance = 0; | |
$context = new Transfer($source_account, $destination_account, 15); | |
$context->execute(); | |
var_dump($source_account->balance, $destination_account->balance); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment