Ошибка в декораторе

То что касается флеша, но не касается ВКонтакте API. Например проблемы при создании прыгающего мячика.
Ответить
Agiliter
Сообщения: 112
Зарегистрирован: 01 фев 2014, 13:46

Ошибка в декораторе

Сообщение Agiliter »

Добрый день!
Пробую разобраться в паттерне Декоратор. В качестве примера программа. Есть класс напитков. У каждого напитка есть описание и цена.

Код: Выделить всё

package  {        public class BeverageBase     {        public var _description:String = ""; // Описание напитка                public function BeverageBase(){}                public function getDescription():String        {            return _description;        }                public function getCost():int        {            return 1;        }     }}
От него наследуют эспрессо, черный чай и т.д.

Код: Выделить всё

package  {    public class Espresso extends BeverageBase     {               public function Espresso()         {            _description = "Espresso";        }                public override function getCost():int        {             return 250;        }    }}
Создан класс добавок. Он наследует от напитков, чтобы можно было оперировать типами в дальнейшем.

Код: Выделить всё

package  {    public class CondimentsDecoratorBase extends BeverageBase     {               public function CondimentsDecoratorBase() {}            }}
Теперь добавляем класс Молоко

Код: Выделить всё

package  {    public class MilkCondiment extends CondimentsDecoratorBase     {        public var _beverage:BeverageBase;                public function MilkCondiment(beverage:BeverageBase)        {            _beverage = beverage;                       _description = _beverage.getDescription + " Milk.";        }                public override function getCost():int        {            return _beverage.getCost + 60;        }           }}
Хотим создать эспрессо с молоком. В main пишем

Код: Выделить всё

var _cappuccino:BeverageBase = new MilkCondiment(new Espresso());trace("Beverage: " + _cappuccino.getDescription() + " Cost: " + _cappuccino.getCost());
Трейсами выдает:
Beverage: function Function() {} Milk Cost: 0

Хотя должен по идее:
Beverage: Espresso. Milk. Cost: 310
Аватара пользователя
alexandr_ratush
Сообщения: 94
Зарегистрирован: 05 мар 2014, 21:47

Re: Ошибка в декораторе

Сообщение alexandr_ratush »

У вас неправильный вызов методов в классе MilkCondiment, нету скобок.
Вот так нужно:

Код: Выделить всё

 ... _description = _beverage.getDescription() + " Milk.";...return _beverage.getCost() + 60;... 
Agiliter
Сообщения: 112
Зарегистрирован: 01 фев 2014, 13:46

Re: Ошибка в декораторе

Сообщение Agiliter »

Спасибо) Сгораю от стыда :)
Так-то декоратор верно реализовал? Если я захочу теперь эспрессо с сахаром молоком, то

Код: Выделить всё

var _cappuccino:BeverageBase = new SugarCondiment(new MilkCondiment(new Espresso()));
И вуаля
Beverage: Espresso. Milk. Sugar. Cost: 370

Однако ж, насколько далеко можно зайти в этаком построении матрешек? Если с молоком, шоколадом, двойным сахаром и фиг знает еще с чем:
Beverage: Espresso. Milk. Chocolate. Sugar. Sugar. Cost: 490

то городить конструкцию вида

Код: Выделить всё

var _cappuccino:BeverageBase = new SugarCondiment(new SugarCondiment(new ChocolateCondiment(new MilkCondiment(new Espresso()))));
???
Аватара пользователя
alexandr_ratush
Сообщения: 94
Зарегистрирован: 05 мар 2014, 21:47

Re: Ошибка в декораторе

Сообщение alexandr_ratush »

Я думаю что если у вас есть кнопка "Кофе с двойным сахаром, с шоколадом, с молоком и еспресо",то конструкция норм. :D

Как я бы сделал? При нажатии на кнопку "Получить кофе", пройтись по всем нажатым кнопкам, и сделать себе кофе:

Код: Выделить всё

 private function getOptions():void{    // Название нажатой кнопки    var tracker: String;    // Проверяем все кнопки    for (var t: uint = 0; t < checks.length; t++)    {        if (checks[t].selected)         {            tracker = checks[t].label;            // По имени нажатой кнопки, декорируем наше кофе            switch (tracker)            {                case "Sugar":                    coffe = new SugarCondiment(coffe);                break;                case "Chocolate":                    coffe = new ChocolateCondiment(coffe);                break;                case "Milk":                    coffe = new MilkCondiment(coffe);                break;                case "Espresso":                    coffe = new Espresso(coffe);                break;            }        }    }} 
P.S.: Пример переделан из той же книги, где декорируют авто.
Agiliter
Сообщения: 112
Зарегистрирован: 01 фев 2014, 13:46

Re: Ошибка в декораторе

Сообщение Agiliter »

alexandr_ratush писал(а):P.S.: Пример переделан из той же книги, где декорируют авто.
Ссылку на книгу можно? :)
Аватара пользователя
alexandr_ratush
Сообщения: 94
Зарегистрирован: 05 мар 2014, 21:47

Re: Ошибка в декораторе

Сообщение alexandr_ratush »

ActionScript 3.0 Design Patterns Можно найти в русском варианте.
Ответить