从其他对象实例访问对象实例的模式

时间:2015-01-10 22:18:52

标签: python design-patterns

提前致谢。鉴于这些类的例子......



    # registers all that happens during a combat
    class CombatLog:
        def __init__(self):
            self.actions = []

    # it handles a combat
    class Combat:
        def __init__(self):
            self.fighters = []   # list of fighter instances
            self.combat_log = CombatLog()
        def run_round(self):
            # do whatever
            self.combat_log.log(...)

    # are the fighters in a combat
    class Fighter:
        def __init__(self):
            self.property1 = 1
            self.property2 = 2
            self.attacks = []  # list of attack instances
        def attack(self):
            # do whatever
            self.combat_log.log(...)  # clean way to access the log?

    class Attack:
        def __init__(self):
            self.damage = 10
        def cast(self):
            # do whatever
            self.combat_log.log(...)  # clean way to access the log?


    # from somewhere else in the code
    combat1 = Combat()
    combat2 = Combat()

我想知道处理下一个要求的最佳模式是什么:

  • 每个Combat有一个唯一的CombatLog实例。因此,如果有2个Combat实例,则战斗将有2个CombatLog实例。
  • 我想在任何地方使用战斗日志。例如,如果战斗机,战斗或攻击,需要访问日志。 CombatLog就像一些"全球"仅在该战斗中的对象和该战斗中的所有实例。
  • 当Combat完成并从内存中移除时,CombatLog也会被移除。

我正在考虑的方法,但我并不自豪/肯定他们:

  • 将日志实例传递给所有子实例(战斗机和攻击)
  • 制作某种日志管理器(如Singleton),然后从我想要的地方请求该战斗的日志。但我有一个类似的问题,那就是我必须将该战斗的id传递给所有chindren,以便请求正确的日志管理器...这比以前的问题更简单。
  • 我正在考虑制作某种依赖注入器,比如使用装饰器等,但我总是遇到同样的问题(前一个)。

也许我需要另一种方法,但我无法想到......代码是用Python编写的。

非常感谢你的时间。

2 个答案:

答案 0 :(得分:1)

如果战斗机只存在于战斗中,请告知它在哪种战斗中:

class Fighter:
    def __init__(self, combat, name):
        self.name = name
        self.combat = combat
    def attack(self):
        self.combat.log.append('{name} attacking'.format(name=self.name))

如果战斗机可以切换战斗,请添加战斗装置:

class Figthter:
    # init(self, name) ...

    def set_combat(combat):
        self.combat = combat

答案 1 :(得分:0)

还有另一个简单的方法,无论如何我认为最好的选择是在指向对象Combat的其他对象中有一个指针,但这似乎不可能:
Pointers in Python?
你可以维护一个战斗字典,并将他们的密钥传递给他们自己和其他对象:

combats = {uuid0: Combat(), uuid1: Combat()}

并像

一样访问它们
class Attack:
    def __init__(self, combatUUID = None):
        self.damage = 10
        if combatUUID: self.combatUUID = combatUUID 
    def cast(self):
        # do whatever
        if self.combatUUID in combats: combats[self.combatUUID].log(...)