Skip to content

Instantly share code, notes, and snippets.

@tankist
Created January 12, 2011 14:42
Show Gist options
  • Save tankist/776230 to your computer and use it in GitHub Desktop.
Save tankist/776230 to your computer and use it in GitHub Desktop.
<?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