组成:我应该访问"内部对象"方法直接?

时间:2015-03-24 11:26:56

标签: python oop

我对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)

如您所见,播放器包含一个Step对象,代表下一步。

我发现我有时想从该Step类访问一个方法。 在这种情况下,最好是向Player添加包装器,例如:

(如果我想访问reset_input()):

class Player(object):
    ...
    def reset_input(self):
        self.step.reset_input()

然后让Player重置输入值:

p = Player()
p.reset_input()

或者更好的做法是直接访问reset_input()

p = Player()
p.step.reset_input()

似乎添加包装器只是重复代码。这也很烦人,因为我需要访问Step的一些方法。

所以,当使用合成(我认为它是正确的术语)时,直接访问'内部'对象方法是不错的做法?

2 个答案:

答案 0 :(得分:3)

我认为你应该在OOP中应用额外的抽象层,如果:

  1. 你预见到你以后会更新代码;和
  2. 代码将在多个地方使用。
  3. 在这种情况下,假设您使用此方法:

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

    然后在代码中的多个位置调用它。稍后,您决定在致电x()之前要执行操作reset_input,将可选参数y传递给reset_input,然后执行操作{{1} } 之后。然后按如下方式更新方法是微不足道的:

    z()

    只需几次按键,代码就会随处更改。想象一下,如果由于你没有使用包装函数而必须更新多个地方的所有调用,那么你手上的噩梦。

    如果您确实预见到使用包装器将更改应用于您的代码,则应该应用包装器。这将使您的代码更易于维护。正如评论中所述,这个概念被称为封装;它允许您使用隐藏实现细节的界面,以便您可以随时轻松更新实现,并以非常简单的方式更改代码。

答案 1 :(得分:1)

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

相关问题