1

我有一个用户对象的方法列表,定义如下:

METHOD_ATTACK: {
    'func': User.handle_attack,
    ...
}

在处理这些动作时,我这样称呼:

user.handle_action(ACTION, *args)

这样做的目的是在 METHOD_* 字典中有各种控制参数,这些参数抽象了对不同功能的控制,例如哪些要求用户处于特定状态才能允许操作继续。如果一切顺利,handle_action 在调用操作方法执行操作之前检查这些条件。

现在:我想创建第二种类型的用户并在派生类中覆盖其中的一些方法,所以如果存在的话,我想调用 SpecialUser.handle_attack 而不是 User.handle_attack。

一种选择是:

METHOD_ATTACK: {
    'func': "handle_attack",
    ...
}

...

func = getattr(user, ACTION["func"])

这增加了一个额外的 getattr 调用来查找每个操作。

另一种选择是为 SpecialUser 复制所有 METHOD_*,但这感觉是多余的。

哪种设计最适合这种变化?

4

1 回答 1

4

一个常见的习惯用法是将这些作为类中的方法,并带有前缀。

class User(object):
    def action_attack(self):
        ...

    def handle_action(self, name):
        method = getattr(self, 'action_' + name)
        method()

class SpecialUser(User):
    def action_attack(self):
        ...

顺便说一句,面向对象的编程意味着对象知道它们的状态并根据消息采取行动。通过将控件放在对象之外,您实际上是在破坏这种机制。因此,只需在用户的方法中检查正确的状态。即使状态是在字典中描述的,也要在对象中检查它们。

于 2013-08-15T03:15:38.517 回答