c# – 在DDD方法中,这个例子是否正确建模?
刚刚创建了一个acc在SO上问这个:)
假设这个简化的例子:构建一个Web应用程序来管理项目… 1)用户应该可以创建插入项目名称的项目. 我使用4层架构(用户界面,应用程序,域,基础架构). public class ProjectService { private IProjectRepository ProjectRepo { get; set; } public ProjectService(IProjectRepository projectRepo) { ProjectRepo = projectRepo; } public void CreateNewProject(string name) { IList<Project> projects = ProjectRepo.GetProjectsByName(name); if (projects.Count > 0) throw new Exception("Project name already exists."); Project project = new Project(name); ProjectRepo.InsertProject(project); } } 在我的域层上,我有Project.cs类和IProjectRepository.cs接口: public class Project { public int ProjectID { get; private set; } public string Name { get; private set; } public Project(string name) { ValidateName(name); Name = name; } private void ValidateName(string name) { if (name == null || name.Equals(string.Empty)) { throw new Exception("Project name cannot be empty or null."); } } } public interface IProjectRepository { void InsertProject(Project project); IList<Project> GetProjectsByName(string projectName); } 在我的基础架构层上,我实现了IProjectRepository,它执行实际的查询(代码是无关紧要的). 我不喜欢这个设计的两件事情: 1)我已经看到存储库接口应该是域的一部分,但实现不应该.这对我来说没有意义,因为我认为域不应该调用存储库方法(持久性无知),这应该是应用层中服务的责任. (有东西告诉我我非常错误.) 2)创建新项目的过程涉及两个验证(不为null且不重复).在我上面的设计中,这两个验证分散在两个不同的地方,使得更难(imho)看到发生了什么. 那么我的问题是,从DDD的角度来看,这个模型是正确的,还是用不同的方法呢? 解决方法
我认为(1)的一部分混乱是你错过了一层 – 在你的架构中插入一个服务层,你的问题就像魔术一样消失.您可以将服务和存储库实现放在服务层中 – 即,您具有使用存储库的具体实现的服务.如果需要,其他服务可以自由地选择存储库的替代实现.您的应用程序可以自由选择它喜欢的任何服务界面.话虽如此,我不知道这在大多数情况下真的很重要.在我几乎所有的应用程序中,我都有一个基本固定的“域/数据层”.我可能会根据业务逻辑的复杂程度来分层存储库.与服务相同 – 如果项目不是很复杂,可能根本就没有必要.如果它变得如此之后,我总是可以重构.通常,我将我的存储库放在与我的数据上下文(使用LINQ)相同的项目中,如果有一个服务,它将在一个单独的项目中(因为通常它将被暴露为Web服务).
关于(2)你需要从并发的角度考虑问题.如果可能,您的检查重复名称最好由数据库约束处理.我认为这是实施这个逻辑的最简单的方法.您可以在尝试插入之前检查是否有重复,但除非在事务中执行此操作,否则不能保证另一个进程不会出现,并在检查和插入之间插入一个进程.数据库约束解决了这个问题.将检查移动到插入逻辑(同一事务)中也解决了问题,但无论我认为您需要准备好处理它作为插入失败以及(或代替)验证错误. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |