1-设计我的实体(在python中):
class Account:
def __init__(name, author):
self.name = name
self.email = email
2-设计我的存储库:(作为接口)
class AccountRepository:
def add(self, account):
""" @type account Account """
pass
def find_by_name(self, name):
pass
def find_by_email(self, email):
pass
# remove, and others...
现在,我可以走两条路:
设计和实现我的域服务:
class SignUpService:
def __init__(self, account_repository):
""" @type account_repository AccountRepository """
self._account_repository = account_repository
def create_account(self, username, email):
account = Account(username, email)
self._account_repository.add(account)
# other methods that uses the account_repository
B:实施我的存储库策略:
class MongodbAccountRepository(AccountRepository):
def __init__(self, mongodb_database):
self._mongodb_database = mongodb_database
def add(self, account):
account_data = account.__dict__
self._mongodb_database.accounts.insert(account_data)
# and the other methods
哪个是正确的顺序?为什么? 1,2,A,B还是1,2,B,A?
非常感谢!
发布于 2014-04-10 10:40:55
首先,我从UI开始,考虑用户需要执行的任务/命令以及每个任务/命令所涉及的数据。这被称为基于任务的UI方法。
这些任务将与应用程序服务提供的方法(与域服务不同)形成1-1映射。
然后,我将根据这些任务&数据来设计我的聚合--一个优化的设计是针对一个任务/事务(),它只涉及一个聚合。对我来说,这就是基于行为设计聚合的意义所在。
我只实现一个事务需要在多个聚合上更改状态的域服务。这些域服务将任何逻辑抽象出应用程序服务(谁的工作仅负责编排)。
存储将是最后一步--只有当您确切地知道正在存储的是什么时,才能实现存储?
所以我的全部命令是:
FYI我倾向于遵循CQRS的原则,所以查询也是我需要考虑的另一个“层”,但我刚刚给出了DDD和设计聚合的顺序。
在设计聚合体的问题上,我推荐沃恩·弗农的这些文章
关于基于行为的聚合设计的我还写了个博客。
发布于 2017-12-05 08:37:01
我个人的观点是,我们应该从业务逻辑所在的地方开始,这就是领域。即使您将在当时实现一个用户故事,您也应该从域和域中的操作开始。我们还应该在领域中应用相同的语言(无处不在的语言)。
在实现和测试之后,rest就自然到来了。您实现了基础设施关注点、应用程序服务、ui。
发布于 2014-04-24 13:34:34
在某种程度上你已经回答了你自己的问题。您的SignUpService
正在使用AccountRepository
,因此您至少需要一些回购实现来进行基本测试。但是,在实践中,当您掌握域时,您可能会看到更多的服务被搅动,因此您可能需要花费更多的时间。
因此,如果您正在寻找经验法则,我建议您首先获得一个工作的存储库实现。它不一定是你的“生产”版本,但它应该能够驱动系统。然后将您的服务和域的其余部分进行更正。领域模型--而不是存储层--是DDD中值的来源,所以请正确选择,让它通知您选择存储后端,而不是相反。
https://softwareengineering.stackexchange.com/questions/235170
复制相似问题