使用继承进行组合重构一个巨大的Python类

2024-10-01 22:35:18 发布

您现在位置:Python中文网/ 问答频道 /正文

几年前我做了一个pygame游戏。它很管用,但不是最好的编码风格,而且有很多经典的代码味道。我最近重新拾起了它,这次尝试用更多的规则来重构它。在

一个很大的代码味道是,我有一个很大的类,GameObject,它继承了pygame.sprite.DirtySprite,其中有很多代码与:

  • 移动精灵的各种方式
  • 设置精灵动画的各种方法
  • 用各种方法引爆精灵
  • 等等

我认为精灵的行为方式越疯狂,代码重复就越多,改变就越困难。因此,我开始将功能分解成许多更小的类,然后在创建对象时将它们传递给:

class GameObject(DirtySprite):
    def __init__(initial_position, mover_cls, imager_cls, exploder_cls):
        self.mover = mover(self, initial_position)
        self.imager = imager(self)
        self.exploder = exploder(self)

...
spaceship = GameObject(pos, CrazyMover, SpaceshipImager, BasicExploder)

当我将越来越多的代码分解到这些helper类中时,代码肯定会更好、更灵活、更少的重复。然而,对于每种类型的helper类,参数的数量越来越长。创建精灵成了一项繁重的工作,代码也很难看。所以,在另一个重构过程中,我创建了一堆非常小的类来进行组合:

^{pr2}$

我更喜欢这种方法。这是一种常见的方法吗?在小类中分解所有的逻辑似乎有相同的好处,但是创建对象要干净得多。在

然而,这种方法并不是动态的。例如,我不能在运行时决定一个新的mashup。然而,这不是我真正在做的事情。很多mashup语句都是静态定义的。在

在未来的可维护性和重用性方面,我是否遗漏了什么?我听说组合比继承好,但这感觉就像我在用继承来做组合,所以我觉得这没问题。在

我应该用不同的模式吗?在


Tags: 方法代码self方式pygame精灵mover重构
1条回答
网友
1楼 · 发布于 2024-10-01 22:35:18

没关系,如果你能很好地分离这些行为-

只是它根本不是“组合”——它是多重继承,使用我们称之为“mixin类”:mixin类大体上是一个提供可以与其他类组合的特定行为的类。在

如果您正确地使用了Python的super,那么这可能是最好的方法。(如果你想创建你的游戏对象,基本上只是定义类名和它使用的mixin类,这实际上是一个非常好的方法)

顺便说一句,如果您想在运行时使用此方法创建新类,也可以-只需调用type来创建新类,而不是使用class语句:

class CrazySpaceship(CrazyMover, SpaceshipImager, BasicExploder, GameObjectAbstract):
    pass  # Many times, all the behavior comes from super classes

在Python中相当于:

^{pr2}$

作为第二个参数使用的元组可以是运行时生成的任何序列。在

相关问题 更多 >

    热门问题