whizark
7/16/2014 - 11:32 AM

DCI in PHP #test #php

DCI in PHP #test #php

<?php
interface AccountInterface
{
    public function getBalance();
    public function increase($money);
    public function decrease($money);
}

trait AccountTrait
{
    private $balance = 0;

    public function getBalance()
    {
        return $this->balance;
    }

    public function increase($money)
    {
        $this->balance += $money;
    }

    public function decrease($money)
    {
        $this->balance -= $money;
    }
}

class Account implements AccountInterface
{
    use AccountTrait;

    public function __construct($balance = 0)
    {
        $this->balance = $balance;
    }
}

interface SenderInterface extends AccountInterface
{
    public function send($money, ReceiverInterface $receiver);
}

interface ReceiverInterface extends AccountInterface
{
    public function receive($money, SenderInterface $sender);
}

// trait DelegatorTrait
// {
//     public function __call($name, $arguments)
//     {
//         // implement
//     }
//
//     public static function __callStatic($name, $arguments)
//     {
//         // implement
//     }
// }

trait AccountRoleTrait
{
    // use DelegatorTrait;
    private $account;

    public function __construct(AccountInterface $account)
    {
        $this->account = $account;
    }

    public function getBalance()
    {
        return $this->account->getBalance();
    }

    public function increase($money)
    {
        $this->account->increase($money);
    }

    public function decrease($money)
    {
        $this->account->decrease($money);
    }
}

class Sender implements SenderInterface
{
    use AccountRoleTrait;

    public function send($money, ReceiverInterface $receiver) {
        $this->decrease($money);
        $receiver->receive($money, $this);
    }
}

class Receiver implements ReceiverInterface
{
    use AccountRoleTrait;

    public function receive($money, SenderInterface $sender) {
        $this->increase($money);
    }
}

class TransferContext
{
    private $sender;
    private $receiver;

    public function __construct(AccountInterface $sender, AccountInterface $receiver)
    {
        $this->sender   = new Sender($sender);
        $this->receiver = new Receiver($receiver);
    }

    public function transfer($money)
    {
        $this->sender->send($money, $this->receiver);
    }
}

$accountA = new Account(10000);
$accountB = new Account(5000);

echo $accountA->getBalance() . PHP_EOL;    // 10000
echo $accountB->getBalance() . PHP_EOL;    // 5000

(new TransferContext($accountA, $accountB))->transfer(5000);

echo $accountA->getBalance() . PHP_EOL;    // 5000
echo $accountB->getBalance() . PHP_EOL;    // 10000