Anu*_*wal 14 python django domain-driven-design ddd-repositories
我对领域驱动设计方法感到困惑.从网上的消息来源我明白这是隔离你的方式Domain Objects
,Database Objects
但我不明白两者之间的区别.
举个例子,我们来看看django教程中的民意调查代码,有两个模型Polls
和Choice
.
这些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')
Run Code Online (Sandbox Code Playgroud)
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()
Run Code Online (Sandbox Code Playgroud)
这是正确的方法吗?我在这里看到了很多冗余代码,但人们说这Polls
是一个域级对象,它不应该直接与数据库对话?
DDD是否总是带有DDD-reposiotry?如果我们有ORM,为什么我们需要一个DDD存储库
另一种方法
views.py
def update_poll(poll_id):
poll = models.Polls.objects.get(poll_id)
poll.question += '?'
poll.save()
Run Code Online (Sandbox Code Playgroud)
这种方法有什么问题?
Chr*_*mon 16
Django专门用于使用这个Django Design Philosophy页面上描述的Active Record Pattern.
您的第二个示例遵循此模式 - 模型本身包含其属性,行为和数据访问.
如果将更多行为推送到模型上,您仍然可以以类似DDD的方式使用此模式.例如,在您的示例中,更有效地使用模式将是包裹线
poll.question += '?'
Run Code Online (Sandbox Code Playgroud)
在一个意图揭示poll对象的update_poll
方法,所以该方法是:
views.py
def update_poll(poll_id):
poll = models.Polls.objects.get(poll_id)
poll.add_question()
poll.save()
Run Code Online (Sandbox Code Playgroud)
这具有将业务逻辑(推入模型)与应用程序流逻辑(update_poll
方法)分离的优点
虽然我建议使用一个名称来实际说明方法的意图或目的,而不仅仅是add_question.
但即使你这样做,你仍然使用Active Record模式,而不是纯DDD.
DDD和ORM正试图解决不同的问题.ORM提供了一种方便的方式,以更面向对象的方式抽象出类似于集合记录的数据库世界.
DDD是一种协助在代码中对复杂的现实世界情况进行建模的方法.
许多DDD系统使用ORM来解决从数据库中检索和保留的基础结构问题(有时由于各种原因将ORM包装在存储库中),但DDD的重点是域模型以及它们对所考虑域的建模的合理程度.
所以 - 在你的例子中,很难看到DDD的好处,因为业务逻辑非常简单.
我建议阅读关于DDD的权威来源 - Eric Evans的域驱动设计,以获得该方法的语言无关概述以及它增加价值的情况.
你问:
你能用一个很好的例子来更新我,其中使用带有ORM的DDD是有意义的
和
如果我们使用ORM,我认为不需要DDD存储库
我认为更好的思考方式是 - 使用ORM时,ORM 是存储库.你问它一个模型,它返回一个模型.这是存储库的目的.当人们将它包装在一个名为"repository"的类中时,通常是因为他们想要做以下几件事之一:
这个存储库模式概述提供了另一个ddd存储库模式的良好编写.
小智 15
Paul Hallett 在他美丽而完整的文章中将所有内容整合在一起:https : //phalt.github.io/post/django-api-domains
和这里的例子:https : //github.com/phalt/django-api-domains
简单来说:
Django 的风格指南已经过时了
文档,从教程到完整文档,讨论了模型-视图-控制器的世界,在这个世界中,Django 呈现 HTML 并将其传送到 Web 浏览器。
这件事让我觉得很奇怪——我从 2012 年开始使用 Django,我只记得用它来渲染 HTML 一次。我在 Django 的几乎所有时间,以及我在会议上看到 Django 被讨论的所有时间都是为前端项目提供 API(通常使用 Django REST 框架)。我认为这实际上是当今 Django 的事实上的标准。对于当前流行的用例,文档已过时。这通常是我在 Django 中看到的一个趋势 - 该项目正在尝试使其运行方式现代化,甚至如何正确处理异步。也许是时候 Django 重新考虑它为开发人员建议的设计模式了?
回到我眼前的问题:为了帮助团队更好地组织他们的软件,我开始从社区中寻找一个好的样式指南。我阅读了域驱动辞职,有界上下文的好处,我找到了 Hacksoft 的一个很好的样式指南,我们尝试使用它。这太棒了!这里的文档非常完善,非常适合小型项目或小型公司。
但是在我们对它的实验过程中,我们发现由于一些原因它不适合用途。即,鼓励业务逻辑存在于模型中的事实。Django 也推荐这个,它基本上是活动记录模式。根据我们在大型团队中的经验,将业务逻辑与模型联系起来会鼓励开发人员用大量代码填充 models.py。这使得开发人员很难同时处理一个文件。更不用说当一个文件在一个域(演示、数据、控制器等)中拥有多个问题时,它往往也会将所有其他问题也吸入文件中。
如果你需要一些关于 DDD 和 Django 的例子,那么这个https://dry-python.org/static/slides/ddd-toolkit-2.html使用dry python 工具的幻灯片可能会很有用。
另外,检查示例项目https://github.com/dry-python/tutorials/tree/master/django/example