首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python中的装饰&访问者模式

Python中的装饰&访问者模式
EN

Code Review用户
提问于 2020-02-18 00:12:16
回答 1查看 386关注 0票数 2

我在python中实现了Visitor和Decorator模式。我非常习惯于java设计模式风格,因此我认为在python中也会尝试。有人能告诉我在Python中这是否是正确的方法吗?

有什么更好的方法吗?

我做了咖啡课,用糖和牛奶装饰它。我有一位客人要计算税款或费用。在TaxVisitor和CostVisitor中,这些值是随机的。

代码语言:javascript
复制
from abc import ABC, abstractmethod


class Visitable(ABC):

    @abstractmethod
    def accept(self, visitor):
        pass

class CostVisitor(ABC):

    @abstractmethod
    def cost(self, node):
        pass

class TaxVisitor(CostVisitor):

    def cost(self,node):
        if isinstance(node, Milk):
            return 150
        if isinstance(node, Sugar):
            return 100
        if isinstance(node, Plain_Coffee):
            return 10

class CostVisitor(CostVisitor):

    def cost(self,node):
        if isinstance(node, Milk):
            return 15
        if isinstance(node, Sugar):
            return 10
        if isinstance(node, Plain_Coffee):
            return 1

class Coffee(Visitable):

    @abstractmethod
    def cost(self):
        raise ValueError('Implement')

    @abstractmethod
    def display(self):
        raise ValueError('Implement')


class Plain_Coffee(Coffee):

    def cost(self):
        return 2

    def display(self):
        return 'Coffee'

    def accept(self, visitor):
        return visitor.cost(self)


class CoffeeDecorator(Coffee):

    def __init__(self, m_base):
        self.m_base = m_base

    def accept(self, visitor):
        return visitor.cost(self) + self.m_base.accept(visitor)


class Milk(CoffeeDecorator):

    def __init__(self, m_base):
        CoffeeDecorator.__init__(self, m_base)

    def cost(self):
        return self.m_base.cost() + 1

    def display(self):
        return self.m_base.display() + ' milk'

class Sugar(CoffeeDecorator):

    def __init__(self, m_base):
        CoffeeDecorator.__init__(self, m_base)

    def cost(self):
        return self.m_base.cost() + .5

    def display(self):
        return self.m_base.display() + ' sugar'



coffee = Plain_Coffee()
coffee = Milk(coffee)
coffee = Sugar(coffee)

print(coffee.accept(CostVisitor()))

```
代码语言:javascript
复制
EN

回答 1

Code Review用户

发布于 2020-02-18 08:27:47

通常,其他语言中的访问者模式是使用表、映射或任何其他结构/对象类型来管理的,下面是您可以对代码进行的改进

代码语言:javascript
复制
class TaxVisitor(CostVisitor):

    def cost(self,node):
        if isinstance(node, Milk):
            return 150
        if isinstance(node, Sugar):
            return 100
        if isinstance(node, Plain_Coffee):
            return 10

可以更改为

代码语言:javascript
复制
class TaxVisitor(CostVisitor):
    self.__table = { "Milk" : 150, "Sugar" : 100, ...}

    def cost(self,node):
        if node.__class__.__name__ in self.__table:
            return self.__table[node.__class__.__name__]

这将使扩展实例的数量变得容易,只需更新表变量,希望是明确的。

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/237467

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档