Created
January 12, 2011 14:42
-
-
Save tankist/776230 to your computer and use it in GitHub Desktop.
This file contains 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 Drinkable { | |
//Это можно пить | |
public function drink(); | |
} | |
class Liquid_Exception extends Exception {} | |
//Абстрактный класс Жидкость | |
abstract class Liquid { | |
//Объем жидкости | |
protected $_amount = null; | |
public function setAmount($amount) { | |
$this->_amount = $amount; | |
return $this; | |
} | |
public function getAmount() { | |
return $this->_amount; | |
} | |
} | |
//Абстрактный класс Кипяченая жидкость | |
abstract class BoiledLiquid extends Liquid { | |
//Уже вскипятили??? | |
protected $_isBoiled = false; | |
//Уже вскипятили??? | |
public function isBoiled() { | |
return $this->_isBoiled; | |
} | |
//Закипятить! | |
public function boil() { | |
$this->_isBoiled = true; | |
return $this; | |
} | |
} | |
//Класс Чай (наследуется от класса Кипяченая жидкость) и его можно пить! | |
class Tea extends BoiledLiquid implements Drinkable { | |
//Количество сахара | |
protected $_sugar = 0; | |
//Лимончику??? | |
protected $_lemon = false; | |
/*public function __construct($sugar = 0, $lemon = false) { | |
$this->boil()->setSugar($sugar)->setLemon($lemon); | |
}*/ | |
//Насыпать сахарку | |
public function setSugar($sugar) { | |
$this->_sugar = $sugar; | |
return $this; | |
} | |
//Сколько сахара? | |
public function getSugar() { | |
return $this->_sugar; | |
} | |
//Кинуть лимончик | |
public function setLemon($lemon) { | |
$this->_lemon = $lemon; | |
return $this; | |
} | |
//А лимончик кинули? | |
public function getLemon() { | |
return $this->_lemon; | |
} | |
//Пьем чай | |
public function drink() { | |
if ($this->getAmount() <=0 ) { | |
throw new Liquid_Exception('А пить-то нечего!!!'); | |
} | |
if (!$this->isBoiled()) { | |
throw new Liquid_Exception('Пить холодный??? Фи!'); | |
} | |
return array( | |
'sugar' => $this->getSugar(), | |
'lemon' => $this->getLemon() | |
); | |
} | |
} | |
class Cup_Exception extends Exception {} | |
//Абстрактный класс Чашка | |
abstract class Cup { | |
//Вместимость чашки | |
protected $_capacity = null; | |
//Содержимое чашки | |
protected $_liquid = null; | |
//Наливаем в чашку жидкость | |
public function fill(Liquid $liquid) { | |
if ($liquid->getAmount() > $this->getCapacity()) { | |
throw new Cup_Exception('Куда ты столько льешь? Кто с пола вытирать будет?'); | |
} | |
$this->_liquid = $liquid; | |
return $this; | |
} | |
//Выливаем жидкость из чашки | |
public function outpour() { | |
$liquid = $this->_liquid; | |
unset($this->_liquid); | |
return $liquid; | |
} | |
//Чашка пустая??? | |
public function isEmpty() { | |
//Проверяем, что в чашке вообще содержиться жидкость и ее объем больше 0 | |
return (!($this->_liquid instanceOf Liquid) || $this->_liquid->getAmount() > 0); | |
} | |
public function setCapacity($capacity) { | |
$this->_capacity = $capacity; | |
return $this; | |
} | |
public function getCapacity() { | |
return $this->_capacity; | |
} | |
public static function factory($type) { | |
$className = ucfirst($type) . 'Cup'; | |
if (class_exists($className, true)) { | |
$reflector = new ReflectionClass($className); | |
//Это чашка вообще? | |
if ($reflector->isSubclassOf('Cup')) { | |
$args = func_get_args(); | |
array_shift($args); | |
return ($reflector->hasMethod('__construct'))?$reflector->newInstanceArgs($args):$reflector->newInstance(); | |
} | |
} | |
return false; | |
} | |
//Магический метод для манипуляций с содержимым чашки, не выливая его | |
public function __call($method, $options) { | |
if (preg_match('$(set|get)Liquid(\w+)$', $method, $m)) { | |
$newMethodName = $m[1].$m[2]; | |
if (method_exists($this->_liquid, $newMethodName)) { | |
return call_user_func_array(array($this->_liquid, $newMethodName), $options); | |
} | |
} | |
throw new Cup_Exception('Такое действие с чашкой выполнять нельзя'); | |
} | |
} | |
class CupsShelf_Exception extends Exception {} | |
//Коллекция чашек на полке | |
abstract class CupsShelf { | |
//Сколько всего чашек в доме? | |
protected static $_totalCupsCount = 0; | |
//Все чашки, которые есть в доме | |
protected static $_cups = array(); | |
public static function setTotalCupsCount($totalCupsCount) { | |
self::$_totalCupsCount = $totalCupsCount; | |
} | |
public static function getTotalCupsCount() { | |
return self::$_totalCupsCount; | |
} | |
public static function init() { | |
if (self::getTotalCupsCount() > 0) { | |
for($i=0;$i<=self::getTotalCupsCount();$i++){ | |
array_push(self::$_cups, Cup::factory('Tea')->setCapacity(0.25)); | |
} | |
} | |
} | |
public static function getCup() { | |
for($i=0;$i<=self::getTotalCupsCount();$i++){ | |
$cup = self::$_cups[$i]; | |
if ($cup->isEmpty()) { | |
return $cup; | |
} | |
} | |
throw new CupsShelf_Exception('Нет свободных чашек'); | |
} | |
} | |
//Класс чашка для чая | |
class TeaCup extends Cup { | |
} | |
try { | |
CupsShelf::setTotalCupsCount(10); | |
CupsShelf::init(); | |
//Достаем чашку с полки | |
$cup = CupsShelf::getCup(); | |
//Завариваем чай | |
$tea = new Tea(); | |
//И закипятить не забыли | |
$tea->boil()->setAmount(0.25); | |
//Наливаем в чашку | |
$cup->fill($tea); | |
//Кинули в чашку сахарку | |
$cup->setLiquidSugar(2.5); | |
//А лимончик мы не любим. Ну его! | |
$cup->setLiquidLemon(false); | |
//Пьем! | |
$cup->outpour()->drink(); | |
} | |
catch (Exception $e) { | |
echo 'Да, не пить тебе чаю сегодня... (' . $e->getMessage() . ')'; | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment