2017-02-04 131 views
1

我对领域驱动设计方法感到困惑。从网上的来源,我明白这是分离你的Domain ObjectsDatabase Objects的方式,但我不明白两者之间的差异。Django和域驱动设计

举一个例子,我们以django教程中的调查例子code为例,有PollsChoice两个模型。

这些是domain level objects还是database level objects

是否需要带ORM的DDD?

如果是的话,你能提供你需要使用DDD方式与ORM

例如一个良好的局面,这是模型

class Polls(models.Model): 
    question = models.CharField(max_length=200) 
    pub_date = models.DateTimeField('date published') 

DDD方法的代码,我看到有人写

class PollService(object): 
    def __init__(self, poll_repository): 
     self.poll_respository = poll_respository 

    def update(self, poll_id): 
     poll = self.poll_respository.fetch_by_id(poll_id) 
     poll.question += '?' 
     self.poll_respository.update(poll) 

#assume that the following code works? 
class PollRepository(): 

    def __init__(self, db): 
     self.db = db 

    def update(self, poll): 
     try: 
      self.db.session().add(poll) 
      self.db.session.commit() 
     except Exception: 
      self.db.session.rollback() 

这是一个正确的方法吗?我在这里看到很多冗余代码,但有人说Polls是一个域对象,它不应该直接与数据库交谈?

DDD是否总是附带DDD-Reposiotry?为什么我们需要一个DDD库,如果我们有一个ORM

另一种方法

views.py 
def update_poll(poll_id): 
    poll = models.Polls.objects.get(poll_id) 
    poll.question += '?' 
    poll.save() 

有什么不对的这种做法?

+0

“DDD是否总是附带DDD-Reposiotry?” - 不可以。您可以使用CQRS与Event Sourcing –

回答

4

活动记录模式

,因为这Django Design Philosophy页上介绍Django是对使用Active Record Pattern量身定做。

您的第二个示例遵循此模式 - 模型本身具有其属性,行为和数据访问。

如果将更多行为推送到模型上,仍然可以以更类似DDD的方式使用此模式。例如在实例中,更有效地利用该图案将是包裹线

poll.question += '?' 

在投票对象的意图揭示的方法,从而使update_poll方法是:

views.py 
def update_poll(poll_id): 
    poll = models.Polls.objects.get(poll_id) 
    poll.add_question() 
    poll.save() 

这具有从应用程序流程逻辑(update_poll方法)中分离出业务逻辑(推入模型)的优势

尽管我建议使用实际说明方法意图或目的的名称,而不仅仅是add_question。

但即使你这样做,你仍然使用活动记录模式,而不是纯粹的DDD。

你问:“是否需要使用ORM的DDD?“

DDD和ORM试图解决不同的问题。奥姆斯提供抽象数据库的设置类似的面向记录的世界,一个更加面向对象的方式的一种便捷方式。

DDD是辅助的方法在代码中建模复杂的真实世界情况

许多DDD系统使用ORM来解决从数据库中检索和维护的基础架构问题(有时由于各种原因将ORM包装到存储库中),但DDD重点是在域模型上以及它们如何适当地模拟正在考虑的域。

因此 - 在您的示例中,由于业务逻辑非常简单,DDD的优势很难看出。

我推荐阅读DDD的授权来源 - Domain Driven Design by Eric Evans,了解该方法的一种语言不可知概述及其增值的情况。

更新

你问:

你能与在使用DDD与ORM一个很好的例子,我更新有道理

如果我们使用ORM我认为不需要DDD库

我想一个更好的方法来思考它 - 当使用ORM时,ORM 存储库。你问它的模型,它返回一个模型。这是存储库的目的。当人们在一个名为“仓库”类包装它通常是因为他们想要做的几件事情之一:

  1. 使其更容易注入模拟库来简化单元测试
  2. 抽象具体 ORM技术用于给灵活地改变ORM后无需触碰服务或域名

overview of the repository pattern提供DDD库模式的另一个很好的书面记录。

+0

谢谢Chris。你能用一个很好的例子来更新我吗?在ORM中使用DDD有意义吗? –

+0

我们是否需要在ORM中使用ddd-repository?如果我们使用ORM,我认为不需要DDD库? –

+1

请注意DDD中的'模型'是'域模型',它由实体,值对象,服务,存储库,聚集,聚集根以及其他任何需要表示相关域的域组成。在Django模型中的模型,是实体。换句话说,在DDD中,模型是域的模型。 – andho