我对OOP还比较陌生,而且肯定还在学习。我想知道在处理这两个类时的最佳实践是什么:
(我已经对一个旧电脑游戏的统计引擎进行了反向工程,但我想这个主题与我的问题无关)

class Step(object):
    def __init__(self):
        self.input = 'G'

    ...more attributes...

    def reset_input(self):
        ''' Reset input to None. '''
        self.input = None
        print '* Input reset.'

        ... more methods ...

然后我有了Player类,它是要控制的主要对象(至少在我的设计中):
class Player(object):
    ''' Represents a player. Accepts initial stats.'''
    def __init__(self, step= 250, off= 13, dng= 50000, dist= 128, d_inc= 113):
        self.route = []
        self.step = Step(step=step, off=off, dng=dng, dist=dist, d_inc=d_inc)
        self.original = copy.copy(self.step)

如您所见,Player包含一个Step对象,表示下一步。
我发现有时我想访问那个Step类中的方法。
在这种情况下,是否最好向Player添加一个包装器,例如:
(如果我想访问reset_input()):
class Player(object):
    ...
    def reset_input(self):
        self.step.reset_input()

然后让播放器重置输入值:
p = Player()
p.reset_input()

或者,最好直接通过以下方式访问reset_input()
p = Player()
p.step.reset_input()

添加包装器似乎只是复制代码。这也很烦人,因为我需要使用很多Step的方法。
所以,在使用composition(我认为这是正确的术语)时,直接访问“inner”对象方法是一个好的实践吗?

最佳答案

我认为,如果出现以下情况,您应该在OOP中应用额外的抽象层:
你预见到自己会在以后更新代码;并且
代码将在多个地方使用。
在这种情况下,假设您使用以下方法:

def reset_input(self):
    self.step.reset_input()

然后在代码中的多个位置调用它。稍后,您决定在调用x()之前执行actionreset_input,将可选参数y传递到reset_input,然后执行actionz()。然后按如下方式更新方法很简单:
def reset_input(self):
    self.x()
    self.step.reset_input(self.y)
    self.z()

只需几下按键,代码就可以在任何地方更改。想象一下,如果由于没有使用包装器函数而不得不在多个位置更新所有调用,那么你将面临一场噩梦。
如果您真的预见到自己将使用包装器对代码应用更改,则应该应用包装器。这将使您的代码更易于维护。如注释中所述,这个概念被称为封装;它允许您使用一个隐藏实现细节的接口,以便您可以随时轻松地更新实现,并且它将以非常简单的方式普遍地更改代码。

07-26 00:00
查看更多