在接受具有网关事务的付款的订单的系统中,对象应如下所示:
class Order(object):
... Inside init ...
self.total_in_dollars = <Dollar Amount>
self.is_paid = <Boolean Value>
class Payment(object):
... Inside init ...
self.order = order_instance
self.amount = order.total_in_dollars
class GatewayTransaction(object):
... Inside init ...
self.payment = payment_instance
self.amount = <Dollar Amount>
Run Code Online (Sandbox Code Playgroud)
这似乎是这样做的方式(显然这不是具有整数美元金额的真实代码,但是你得到了图片).我是这样做的,因为订单可以在没有付款的情况下存在,并且在实际的PayPal交易发生之前可以存在付款.这是否缺乏你的意见?我的思考是否倒退?
或者,它应该更像这样:
class GatewayTransaction(object):
payment = payment_instance
amount = <Dollar Amount>
class Payment(object):
amount = <Dollar Amount>
gateway_transaction = gateway_transaction_instance
class Order(object):
amount_in_dollars = <Dollar Amount>
payment = payment_instance
Run Code Online (Sandbox Code Playgroud)
你似乎正在分配显然应该是实例变量的类变量,这显然是一个非常错误的方法.IOW,变量应该是self.total_in_dollars(例如Order)等等,在语句中分配__init__,而不是类变量class.
简单地创建一个Order没有相应实例的实例Payment很好(并且显然应该设置is_paid为False),仅基于总数(并且可能是一些数字ID,因此客户和c可以在将来引用特定订单).
不要不必要地复制信息!由于Payment实例将始终有一个参考Order实例,它应该不会复制self.order.total_in_dollars到self.amount-更好地在信息一个地方(你可以做一个只读的property,如果你想很好的访问); 对于事务实例更是如此.
如果Order实例携带了影响相应Payment实例的创建和行为方式的进一步元数据,那没关系,但强烈建议将Payment实例的创建作为Object类的工厂方法的工作(然后它也可以跟踪已经生成的实例,并确保单个给定订单实例永远不会有多个Payment实例).
编辑:既然OP已经在某种程度上编辑了A,我可以确认第一版中的依赖关系大致是正确的(除了,数量不应该在整个地方被复制),而第二个版本中的依赖关系是表面上看,不正确(例如,相互/循环依赖的存在总是一种设计气味,除非明确和明确地通过特殊应用需求证明 - 即使需要来回导航,两个链接中的一个应该至少是一个弱的参考).
编辑:因为OP明确要求我建议的工厂方法的更多细节,我想到的是这样的:
import weakref
class Payment(object):
def __init__(self, order):
self.order = weakref.proxy(order, self.ordergone)
def ordergone(self, *_):
self.order = None
@property
def amount(self):
if self.order is None: return None
else: return self.order.total_in_dollars
class Order(object):
def __init__(self, amount):
self.total_in_dollars = amount
self.is_paid = False
self._payment = None
@property
def payment(self):
if self._payment is None:
self._payment = Payment(self)
return self._payment
Run Code Online (Sandbox Code Playgroud)