对象应该知道他们使用的对象吗?

时间:2018-02-21 18:14:14

标签: oop object

class Item:
    def __init__(self, box, description):
        self._box = box
        self._description = description

class Box:
    def __init__(self):
        self.item_1 = Item(self, 'A picture')
        self.item_2 = Item(self, 'A pencil')
        #etc

old_stuff = Box()
print(old_stuff.item_1.box.item_1.box.item_2.box.item_1)

上面显示了一段代码示例,它比我用纯文本更好地演示了我的问题。有没有更好的方法来找到什么盒子? (在什么方面是图片?)因为我不是特别喜欢上面的解决方案,因为它允许这种奇怪的上下呼叫可以永远持续下去。有没有更好的方法来解决这个问题,或者这只是一个案例:如果它是愚蠢的并且它有效,那就不是傻了。

注意:这个技巧不是特定于python的。它在所有面向对象的编程语言中都是可行的。

2 个答案:

答案 0 :(得分:1)

您必须引入新的类 - ItemManager或简单的字典或其他外部结构来存储有关哪个方框包含您的项目的信息:

class Item:
    def __init__(self, description):
        self.description = description


class Box:
    def __init__(self, item_1, item_2):
        self.item_1 = item_1
        self.item_2 = item_2


class ItemManager:
    def __init__(self):
        self.item_boxes = {}

    def register_item(self, item, box):
        self.item_boxes[item] = box

    def deregister_item(self, item):
        del self.item_boxes[item]

    def get_box(self, item):
        return self.item_boxes.get(item, None)


item_manager = ItemManager()
item_1 = Item("A picture")
item_2 = Item("A pencil")
item_3 = Item("A teapot")
old_stuff = Box(item_1, item_2)
item_manager.register_item(item_1, old_stuff)
item_manager.register_item(item_2, old_stuff)
new_stuff = Box(item_3, None)
item_manager.register_item(item_3, new_stuff)

box_with_picture = item_manager.get_box(item_2)
print box_with_picture.item_1.description

另请参阅SRP:项目不应知道哪个框包含它。

答案 1 :(得分:1)

这可能不是您所期望的答案,但实际上没有正确或错误的方法来做到这一点。这一切都取决于你打算如何使用这个对象。

如果您的用例要求某个项目知道它存储在哪个框中,那么您需要保留对该框的引用;如果没有,你就不需要这种关联。

同样,如果您需要知道框中的项目,则需要保留对框对象中项目的引用。

您如何设计您的班级模型取决于当前的要求。我的意思是"立即"是"在当前的背景下&#34 ;;例如,您在UX中对项目或框进行建模的方式与在服务层中对其进行建模的方式不同。