标签: domain-driven-design

Symfony应用程序中的Doctrine实体和业务逻辑

欢迎任何想法/反馈:)

我遇到了如何在一个大型Symfony2应用程序中处理我的Doctrine2实体的业务逻辑的问题.(抱歉帖子长度)

在阅读了许多博客,食谱和其他资源后,我发现:

  • 实体可能仅用于数据映射持久性("贫血模型"),
  • 控制器必须更小,
  • 域模型必须与持久层分离(实体不知道实体管理器)

好吧,我完全同意它,但是: 在哪里以及如何处理域模型上复杂的业务规则?


一个简单的例子

我们的域名模型:

  • 一个可以使用角色
  • a 角色可以由不同的组使用
  • 一个用户可以属于多个与许多角色,

SQL持久层中,我们可以将这些关系建模为:

在此输入图像描述

我们的具体业务规则:

  • 仅当角色附加到组时,用户才能在组中拥有角色.
  • 如果我们从组G1中分离角色R1,则必须删除具有组G1和角色R1的所有UserRoleAffectation

这是一个非常简单的例子,但我想知道管理这些业务规则的最佳方法.


找到解决方案

1-服务层实现

使用特定的Service类:

class GroupRoleAffectionService {

  function linkRoleToGroup ($role, $group)
  { 
    //... 
  }

  function unlinkRoleToGroup ($role, $group)
  {
    //business logic to find all invalid UserRoleAffectation with these role and …
Run Code Online (Sandbox Code Playgroud)

php domain-driven-design symfony doctrine-orm

56
推荐指数
2
解决办法
1万
查看次数

非程序化软件开发是否可行?

我目前面临着一个非常不寻常的设计问题,希望比我更聪明的开发人员能够提供一些见解.

背景

没有太具体,我被非营利组织聘用,以协助重建他们的遗产,但非常有价值(在社会价值方面)软件.开发团队不同于我作为软件开发人员时遇到的任何开发团队,由少数开发人员和更多非编程领域专家组成.这种安排的不寻常之处在于领域专家(我们称之为内容创建者),使用自定义工具(其中一些基于prolog专家系统引擎)来开发基于Web的软件组件/表单.

问题

系统使用非常笨拙的回发模型来执行服务器端的逻辑操作并返回新的表单/结果.它很慢,容易出现故障.简单的东西,比如利用现有的工具创建HTML表单是多少更艰巨的比它应该是.随着对更具交互性和高性能体验的需求的增长,软件开发人员越来越多地发现他们必须绕过内容创建者使用的专家系统/可视化工具,并在javascript中手动编写新组件.内容创作者越来越感到他们的双手被束缚,因为他们现在无法贡献新的组件.

设计方法:传统/典型

我一直在倡导完全放弃以前的模型并采用典型的软件开发过程.如前所述,由于非程序化开发工具已无法满足业务需求,因此该项目自然而然地向此发展.

然而,内容创建者可以做出非常宝贵的贡献,我希望他们能够专注于使用像Cucumber这样的工具正式指定软件的预期行为,而不是参与实现.

设计方法:非程序化

我的同事,我非常尊重和怀疑,比我更有知识,认为现有的过程很好,我们只需要建立更好的工具.然而我不禁觉得这种方法存在根本性的缺陷.我还没有找到一个实例,无论是历史还是现代,这种软件开发模式都取得了成功.COBOL的开发理念是允许业务人员/领域专家在不需要程序员的情况下编写应用程序,在我看来,所有这些都是创建一种新的程序员 - COBOL程序员.如果有可能开发出有效的系统,允许非程序员创建非平凡的应用程序,对程序员的需求肯定会低得多吗?我所知道的唯一适合这种模式的框架是SAP的Smart Forms和Microsoft的Dynamix AX--这两个框架都是特定领域的ERP系统.

DSL,模板语言

这两个概念之间的妥协是将某种DSL作为模板语言来实现.我甚至不确定这会成功,因为除了一个例外,所有内容创建者都完全不是技术性的.

我还考虑使用图形/工具箱样式工具构建基于Visual Studio或Net Beans的自定义IDE.

思考?

非程序化开发是一个愚蠢的错误吗?这总是会导致一些令人不满意的事情,需要程序员亲自动手吗?

非常感谢您花时间阅读本文,我当然感谢任何反馈.

domain-driven-design

54
推荐指数
4
解决办法
1814
查看次数

DDD是浪费时间吗?

谷歌搜索"DDD适合哪种应用?" 给了我以下答案:

可能95%的软件应用程序属于"使用DDD不太好"的类别.(见文章)

那么大惊小怪的是什么?!?

我正在处理的应用程序主要是以数据为中心,但仍然包含一些应用的业务逻辑和规则.开始应用DDD技术会浪费时间吗?我最好使用更传统的数据访问层,POCO模型和业务逻辑层吗?或者以不同的方式说明 - 什么是DDD的声音替代品?

oop domain-driven-design

53
推荐指数
7
解决办法
1万
查看次数

DDD和MVC:'模型'和'实体'之间的区别

我对MVC中"模型"的概念感到非常困惑.今天存在的大多数框架将模型放在Controller和数据库之间,而模型几乎就像数据库抽象层.随着Controller开始做越来越多的逻辑,'Fat Model Skinny Controller'的概念就丢失了.

在DDD中,还有域实体的概念,它具有唯一的身份.据我了解,用户是实体的一个很好的例子(例如,唯一的用户ID).实体有一个生命周期 - 它的值可以在整个动作过程中改变 - 然后它被保存或丢弃.

我上面描述的实体是我认为模型应该在MVC中的内容?我有多偏离基础?

为了使事情更加混乱,你会引入其他模式,例如Repository模式(可能会在其中放置一个Service).很清楚Repository如何与实体交互 - 它与模型有什么关系?

控制器可以有多个模型,这使得模型看起来像一个"数据库表"而不是一个独特的实体.

更新: 在这篇文章中,模型被描述为具有知识的东西,它可以是单数或对象的集合.所以听起来更像是一个实体,一个模型或多或少都是一样的.模型是一个包罗万象的术语,其中实体更具体.值对象也是一个模型.至少在MVC方面.也许???

所以,从非常粗略的角度来看,哪个更好?

没有"模特"真的......

class MyController {
    public function index() {
        $repo = new PostRepository();
        $posts = $repo->findAllByDateRange('within 30 days');
        foreach($posts as $post) {
            echo $post->Author;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

或者这个,它有一个模型作为DAO?

class MyController {
    public function index() {
        $model = new PostModel();
        // maybe this returns a PostRepository?
        $posts = $model->findAllByDateRange('within 30 days');
        while($posts->getNext()) {
            echo $posts->Post->Author;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这两个例子都没有做我上面描述的内容.我很丢失.有什么输入?

php model-view-controller entity domain-driven-design model

53
推荐指数
3
解决办法
2万
查看次数

服务层如何适合我的存储库实现?

我创建了一个POCO模型类和一个处理持久性的存储库类.由于POCO无法访问存储库,因此存储库中有许多业务逻辑任务似乎不对.根据我的阅读,看起来我需要一个位于UI使用者和存储库层之间的服务层.我不确定的是它应该如何工作......

除了服务层,还应该有一个单独的业务逻辑层,还是那个服务层的角色?

每个存储库应该有一个服务吗?

服务层是UI可以实例化模型对象还是存储库为服务提供新模型实例的唯一方式?

我是否将我的参数,模型和其他验证放在服务层中进行检查以确保输入有效以及更新前数据库中是否存在要更新的项目?

模型,存储库和UI都可以调用服务层,还是仅供UI使用?

服务层应该是所有静态方法吗?

从UI调用服务层的典型方法是什么?

模型与服务层应该进行哪些验证?

以下是我现有图层的示例代码:

public class GiftCertificateModel
{
    public int GiftCerticiateId {get;set;}
    public string Code {get;set;}
    public decimal Amount {get;set;}
    public DateTime ExpirationDate {get;set;}

    public bool IsValidCode(){}
}


public class GiftCertificateRepository
{
    //only way to access database
    public GiftCertificateModel GetById(int GiftCertificateId) { }
    public List<GiftCertificateModel> GetMany() { }
    public void Save(GiftCertificateModel gc) { }
    public string GetNewUniqueCode() { //code has to be checked in db }

    public GiftCertificateModel CreateNew()
    {
        GiftCertificateModel gc = new …
Run Code Online (Sandbox Code Playgroud)

c# asp.net domain-driven-design repository repository-pattern

52
推荐指数
1
解决办法
1万
查看次数

DDD - 持久性模型和领域模型

我正在尝试学习域驱动设计(DDD),我认为我有了基本的想法.但是有些让我困惑的事情.

在DDD中,持久性模型和域模型是不同的东西?我的意思是,我们设计的域名和类只考虑了域名问题; 没关系.但在那之后,当我们构建我们的存储库或任何其他数据持久性系统时,我们是否应该创建另一个模型以在持久层中使用?

我在想我们的域模型也用于持久化,这意味着我们的存储库从查询返回我们的域对象.但今天,我读了这篇文章,我有点困惑:

刚刚停止!域模型不是持久性模型

如果这是真的,那么从域对象中获得单独的持久性对象会有什么好处?

oop domain-driven-design model repository repository-pattern

51
推荐指数
3
解决办法
2万
查看次数

什么是域驱动设计?

所以我从团队中的一位开发人员那里得到了这个问题:什么是域驱动设计?我当然可以指出埃文斯的这本书,但这实际上是一个答案吗?

您如何用几句话向团队中的初级软件工程师解释DDD?

domain-driven-design

49
推荐指数
3
解决办法
7339
查看次数

域驱动设计中的访问控制

我读到了DDD和访问控制,我发现以下两种观点之间存在一些矛盾:

  • "安全问题应该在域外处理"
  • "访问控制要求是特定于域的"

我正在寻找关于此的最佳实践.那么我应该在哪里通过域驱动设计放置访问控制逻辑,我应该如何实现它?

(更具体地说,DDD + CQRS + ES.)

我认为它应该接近业务逻辑,例如用户故事可能是这样的:

用户可以通过发送用户名,爱好列表,简历等来编辑他的个人资料...

根据用户故事,我们实现了域模型和服务,例如:

UserService
    editProfile(EditUserProfileCommand command)
        User user = userRepository.getOneById(command.id)
        user.changeName(command.name)
        user.changeHobbies(command.hobbies)
        user.changeCV(command.cv)

UserRepository
    User getOneById(id)

User
    changeName(String name)
    changeHobbies(String[] hobbies)
    changeCV(String cv)
Run Code Online (Sandbox Code Playgroud)

这没关系,但HIS profile故事的一部分在哪里?

这显然是基于属性的访问控制,因为我们应该写一个这样的规则:

deny all, but if subject.id = resource.owner.id then grant access
Run Code Online (Sandbox Code Playgroud)

但是我们应该在哪里执行这条规则,我们应该如何实施呢?

security domain-driven-design access-control

49
推荐指数
1
解决办法
1万
查看次数

领域驱动设计和工厂类的作用

我不清楚工厂阶级的角色和责任是什么.我知道,工厂类应该是域对象(聚合根)及其关联实体和值对象的创建.

但是我不清楚的是工厂"层"在于DDD架构?工厂应该直接调用存储库来获取其数据还是服务库?

工厂在哪里适合以下框架:
UI> App> Domain> Service> Data

另外,因为工厂是唯一允许创建对象的地方,如果你想在数据和服务层创建对象,你会不会得到循环引用?

如果工厂类的角色是用于创建对象,那么服务层有哪些好处?

我问了很多问题,并感谢任何回应.我所缺少的是一个示例应用程序,它演示了域驱动设计项目中的所有层是如何组合在一起的...那里有什么东西吗?

design-patterns domain-driven-design

47
推荐指数
3
解决办法
2万
查看次数

在DDD中具有单独的域模型和持久性模型

我一直在阅读有关域驱动设计以及如何使用代码优先方法生成数据库的方法.根据我的阅读和研究,围绕这个主题有两种观点:

  1. 有1个类同时用作域模型和持久性模型

  2. 有2个不同的类,一个实现域逻辑,一个用于代码优先方法

现在我知道意见1)据说简化了在域和持久性模型之间没有太多差异的小解决方案,但我认为它打破了单一责任原则,并且当ORM的约定干扰DDD时引入了许多问题.

令我感到意外的是,有很多关于如何实现意见的代码示例1).但是还没有找到一个如何实现意见的例子2)以及如何映射这两个对象.(可能有这样的例子,但我找不到C#)

所以我试着自己实现一个例子,但我不确定这是不是一个很好的方法.

假设我有一个票务系统,票证有到期日.我的域名模型如下所示:

/// <summary>
/// Domain Model
/// </summary>
public class TicketEntity
{
    public int Id { get; private set; }

    public decimal Cost { get; private set; }

    public DateTime ExpiryDate { get; private set; }

    public TicketEntity(int id, decimal cost, DateTime expiryDate)
    {
        this.Id = id;
        this.Cost = cost;
        this.ExpiryDate = expiryDate;
    }

    public bool IsTicketExpired()
    {
        if (DateTime.Now > this.ExpiryDate)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

使用Entity …

c# architecture orm domain-driven-design domain-model

46
推荐指数
2
解决办法
5832
查看次数