SpecialistOff.NET / Вопросы / Статьи / Фрагменты кода / Резюме / Метки / Помощь / Файлы
НазадМетки: python
Another approach would be to break the drinks down into the various components such as espresso and foamed milk, and then let the customer combine the components to describe a particular coffee.
In order to do this programmatically, we use the Decorator pattern. A Decorator adds responsibility to a component by wrapping it, but the Decorator conforms to the interface of the component it encloses, so the wrapping is transparent. Decorators can also be nested without the loss of this transparency.

Methods invoked on the Decorator can in turn invoke methods in the component, and can of course perform processing before or after the invocation.
So if we added getTotalCost() and getDescription() methods to the DrinkComponent interface, an Espresso looks like this:
# Decorator/alldecorators/EspressoDecorator.py
class Espresso(Decorator):
    cost = 0.75f
    description = " espresso"
    def __init__(DrinkComponent):
        Decorator.__init__(self, component)
    def getTotalCost(self):
        return self.component.getTotalCost() + cost
    def getDescription(self):
        return self.component.getDescription() +
            description
You combine the components to create a drink as follows, as shown in the code below:
# Decorator/alldecorators/CoffeeShop.py
# Coffee example using decorators
class DrinkComponent:
    def getDescription(self):
        return self.__class__.__name__
    def getTotalCost(self):
        return self.__class__.cost
class Mug(DrinkComponent):
    cost = 0.0
class Decorator(DrinkComponent):
    def __init__(self, drinkComponent):
        self.component = drinkComponent
    def getTotalCost(self):
        return self.component.getTotalCost() + \
          DrinkComponent.getTotalCost(self)
    def getDescription(self):
        return self.component.getDescription() + \
          ' ' + DrinkComponent.getDescription(self)
class Espresso(Decorator):
    cost = 0.75
    def __init__(self, drinkComponent):
        Decorator.__init__(self, drinkComponent)
class Decaf(Decorator):
    cost = 0.0
    def __init__(self, drinkComponent):
        Decorator.__init__(self, drinkComponent)
class FoamedMilk(Decorator):
    cost = 0.25
    def __init__(self, drinkComponent):
        Decorator.__init__(self, drinkComponent)
class SteamedMilk(Decorator):
    cost = 0.25
    def __init__(self, drinkComponent):
        Decorator.__init__(self, drinkComponent)
class Whipped(Decorator):
    cost = 0.25
    def __init__(self, drinkComponent):
        Decorator.__init__(self, drinkComponent)
class Chocolate(Decorator):
    cost = 0.25
    def __init__(self, drinkComponent):
        Decorator.__init__(self, drinkComponent)
cappuccino = Espresso(FoamedMilk(Mug()))
print(cappuccino.getDescription().strip() + \)
  ": $" + `cappuccino.getTotalCost()`
cafeMocha = Espresso(SteamedMilk(Chocolate(
  Whipped(Decaf(Mug())))))
print(cafeMocha.getDescription().strip() + \)
  ": $" + `cafeMocha.getTotalCost()`
This approach would certainly provide the most flexibility and the smallest menu. You have a small number of components to choose from, but assembling the description of the coffee then becomes rather arduous.
If you want to describe a plain cappuccino, you create it with:
plainCap = Espresso(FoamedMilk(Mug()))
Creating a decaf Cafe Mocha with whipped cream requires an even longer description.