收集对象的最佳设计模式

时间:2017-07-25 12:27:03

标签: python design-patterns

我有以下架构:

         +-----------------+
         |   Collection    |
         |                 |
         |                 |
         |                 |
         |                 |
         +-----------------+
           |        ^
           |        |
  Create() |        |
           |        |
           v        | GetItem(B)
+------------+      |
|   Item A   |      |
|            |      |
|            +------+
|            |
+------------+

管理项目集合的类,创建项目。这些物品可能需要收集其他物品。

实际代码是在python中,现在Collection将自身作为参数传递给创建的Item。在我看来,这是一个不好的做法。唯一的改进我可以看到它传递Collection所需的Item的几个函数,而不是整个实例。

例如:

class Collection:
    GetItem(self, id):
        ...
    CreateItem(self, id):
        item = Item(id, self) # <-- pass self
        ...

class Item:
    __init__(self, id, col):
        ...
        col.GetItem(...)

如何避免将self作为参数传递?或者它是Python中的常见用法?

更详细的例子

 ┌──────┐            ┌──────────┐           ┌─────┐                              
 │Client│            │Collection│           │ItemA│                              
 └──┬───┘            └────┬─────┘           └──┬──┘                              
    │ UpdateItem(A, param)│                    │                                 
    │ ────────────────────>                    │                                 
    │                     │                    │                                 
    │                     │ Update(param, self)│  ╔═════════════════════════════╗
    │                     │ ───────────────────>  ║Need to update linked ItemB ░║
    │                     │                    │  ╚═════════════════════════════╝
    │                     │     GetItem(B)     │                                 
    │                     │ <───────────────────                                 
    │                     │                    │                                 
    │                     │        ItemB       │                                 
    │                     │  ─ ─ ─ ─ ─ ─ ─ ─ ─ >                                 
    │                     │                    │                                 
    │                     │                    │────┐                            
    │                     │                    │    │ UpdateItemB()              
    │                     │                    │<───┘                            
 ┌──┴───┐            ┌────┴─────┐           ┌──┴──┐                              
 │Client│            │Collection│           │ItemA│                              
 └──────┘            └──────────┘           └─────┘                              

2 个答案:

答案 0 :(得分:1)

非答案:鉴于目前的详细程度,推荐特定模式是错误的做法!从DDD的角度来看,我想知道你是否应该退一步,并且应该从整体上看你的模型。

看起来你的“集合”类中至少有两个职责:

  • 创建对象的知识
  • 更新他们

DDD建议让factories负责创建对象。

而不是考虑提供对所有种类条目的访问权限的集合,您可能宁愿定义聚合,并标识其 root objects 即可。因为您希望确保只有一个定义的“路径”来获取某些信息。

换句话说:您应该努力设计一个模型,为您正在处理的现实世界元素提供有用的抽象。而你当前的实现感觉就像是从一些技术思想演变出来的东西。因此建议:退一步看看图片。

答案 1 :(得分:0)

似乎是使用复合模式的经典之地: https://sourcemaking.com/design_patterns/composite

每个实例都可以是一个集合或一个项目,您的客户可以互换使用它们。