合成:我应该直接访问“内部对象”方法吗?

2024-04-23 22:34:23 发布

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

我对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类访问一个方法。 在这种情况下,是否最好向播放器添加包装,例如:

(如果我想访问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()

似乎添加包装器只是复制代码。这也很烦人,因为我需要访问相当多的步骤的方法。你知道吗

那么,在使用composition(我认为这是正确的术语)时,直接访问“内部”对象方法是否是一种好的实践?你知道吗


Tags: 对象方法selfinputobjectdistdefstep
2条回答

我认为,如果出现以下情况,您应该在OOP中应用额外的抽象层:

  1. 您预计自己稍后会更新代码;并且
  2. 代码将在多个地方使用。你知道吗

在这种情况下,假设您使用以下方法:

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

然后在代码中的多个地方调用它。稍后,您决定在所有对reset_input的调用之前执行操作x(),将可选参数y传入reset_input,然后执行操作z()。那么,按如下方式更新方法就很简单了:

def reset_input(self):
    self.x()
    self.step.reset_input(self.y)
    self.z()

只需几次按键,代码就会在任何地方更改。想象一下,如果你因为没有使用包装器函数而不得不在多个地方更新所有调用,你会有一场噩梦。你知道吗

如果您实际预见到自己使用包装器对代码应用更改,那么应该应用包装器。这将使您的代码更易于维护。如注释中所述,这个概念被称为封装;它允许您使用隐藏实现细节的接口,以便您可以随时轻松地更新实现,并且它将以非常简单的方式通用地更改代码。你知道吗

这总是一种权衡。看Law of Demeter。它描述了您的情况以及不同解决方案的优缺点。你知道吗

相关问题 更多 >