Читая про дизайн по контракту, я наткнулся на PHP-сделка. Теперь его демонстрационный код выглядит так:
/** @var Composer\Autoload\ClassLoader $loader */
$loader = include __DIR__.'/../vendor/autoload.php';
$loader->add('Demo', __DIR__);
include_once __DIR__.'/aspect_bootstrap.php';
$account = new Demo\Account();
$account->deposit(100);
echo $account->getBalance();
Demo\Account
класс выглядит так:
class Account implements AccountContract
{
/**
* Current balance
*
* @var float
*/
protected $balance = 0.0;/**
* Deposits fixed amount of money to the account
*
* @param float $amount
*
* @Contract\Verify("$amount>0 && is_numeric($amount)")
* @Contract\Ensure("$this->balance == $__old->balance+$amount")
*/
public function deposit($amount)
{
$this->balance += $amount;
}/**
* Returns current balance
*
* @Contract\Ensure("$__result == $this->balance")
* @return float
*/
public function getBalance()
{
return $this->balance;
}
}
Аннотации являются важной частью, поскольку они проверяют и гарантируют выполнение контракта в аннотациях.
Вызов классу так:
$account = new Demo\Account();
$account->deposit(100);
echo $account->getBalance();
работает как положено. Однако, вызывая класс так:
$account = new Demo\Account();
$account->deposit("1notanumber");
echo $account->getBalance();
Выдает исключение о неисполнении договора.
Однако, если я назову класс так:
$account = new Demo\Account();
$account->deposit("1notanumber");
echo $account->getBalance();
include_once __DIR__.'/aspect_bootstrap.php';
$account = new Demo\Account();
$account->deposit("1notanumber");
echo $account->getBalance();
Приведение в исполнение контракта перестает работать. У меня вопрос, как aspect_bootstrap.php
файл переопределяет предопределенные классы PHP, позволяющие анализировать и выполнять аннотации, и как можно было бы обойтись без вызова всей инфраструктуры Go AOP?
Задача ещё не решена.
Других решений пока нет …