简体   繁体   English

这叫什么类型的架构?

[英]What type of architecture is this called?

For the web application (ASP.NET MVC) I'm currently developing, we have the following architecture in place: 对于我当前正在开发的Web应用程序(ASP.NET MVC),我们具有以下架构:

  • Data Access Layer : Logic for persisting data to an arbitrary db Data Access Layer :用于将数据持久存储到任意数据库的逻辑
  • Domain : The data model Domain :数据模型
  • Service Layer : Business logic (eg order processing, account management, etc.) Service Layer :业务逻辑(例如订单处理,帐户管理等)
  • Controller : Consumes services and provides/receives data to/from the View Controller :使用服务并向视图提供数据/从视图接收数据
  • View : The user interface for the user View :用户的用户界面

In essence, I took the Model and split it up into the DAL , Service Layer and Domain . 本质上,我采用了Model并将其分为DALService LayerDomain I felt that stuffing all the logic within the Model made my code overly complicated. 我觉得将Model所有逻辑塞满会使我的代码过于复杂。 Furthermore, I felt that it let me express my business logic cleanly without making the controller do too much work. 此外,我觉得它可以使我清晰地表达我的业务逻辑,而无需使控制器做过多的工作。

My question then is: What is this type of architecture called? 那么我的问题是:这种类型的架构叫什么?

As a secondary question : Does this type of architecture make sense? 作为第二个问题 :这种类型的体系结构有意义吗? If not, am I doing something wrong? 如果没有,我做错什么了吗?

You are on the right track about DDD depending on how thin / thick the domain & service layers are. 您对DDD的看法是正确的,具体取决于域和服务层的厚度。 DDD says that the knowledge (ie business logic) should be crunched into the domain model. DDD表示,知识(即业务逻辑)应纳入领域模型。 Moving data access concerns to the DAL is in line with DDD, but I think moving business logic out into a Services Layer is not. 将数据访问问题转移到DAL与DDD一致,但是我认为将业务逻辑转移到服务层是不对的。 If you have a thin Domain "data model" layer (mostly for entities) and a thick Services layer (mostly for "business logic"), you may have an anemic domain . 如果您有一个薄的“域”数据模型”层(主要用于实体)和一个厚的“服务”层(主要是“业务逻辑”),则您可能具有贫乏的域

Also, there is technically no "Service Layer" in DDD. 同样,在DDD中,技术上也没有“服务层”。 There may be an "Application Layer", but it should be thin, and only be responsible for application flow / managing domain class lifetimes. 可能有一个“应用程序层”,但它应该很薄,并且仅负责应用程序流/管理域类的生命周期。 This is essentially what Controllers do in .NET MVC, manage application flow in the context of web http. 实质上,这是Controller在.NET MVC中所做的工作,是在Web http上下文中管理应用程序流。

If stuffing all of the logic within the Model made your code overly complicated, I'd be interested to hear examples of what you mean by "overly complicated". 如果将模型中的所有逻辑塞满,会使您的代码过于复杂,那么我想听听“过度复杂”的含义示例。 You could be correctly modeling a complex domain, or there are chances you could have gone to DDD patterns to uncomplicate things. 您可能正在正确地建模复杂的域,或者有可能您已经使用DDD模式简化了事情。 I would say as you have listed it in your question, the arch is not DDD. 我会说,正如您在问题中列出的那样,拱门不是DDD。 I would just call it "Layered architecture", but that's because I prefer to use the term "tier" only when talking about physical arch. 我将其称为“分层体系结构”,但这是因为我更喜欢仅在谈论物理拱门时使用“层”一词。 However, your logical architecture is layered. 但是,您的逻辑体系结构是分层的。

I really like that Darin linked to Onion arch in his answer. 我真的很喜欢达林在他的回答中链接到洋葱拱门。 I'm becoming a big fan of it, and I find it's not exclusive to DDD at all. 我正在成为它的忠实拥护者,而且我发现它并不是DDD独有的。 If your code uses dependency injection to solve interface dependencies with runtime implementations, you may have a form of onion arch. 如果您的代码使用依赖项注入来解决运行时实现中的接口依赖项,则您可能会有一种形式的洋葱拱。 For example, do you define any interfaces in your DAL? 例如,您是否在DAL中定义了任何接口? Are implementations of those interfaces solved at runtime? 这些接口的实现是否在运行时解决?

Here is an example of an arch I am starting to use in my new projects. 这是我在新项目中开始使用的拱门的示例。 It's a combination of onion + DDD: 它是洋葱+ DDD的组合:

  • API Project/Assembly: generic interfaces, enums, classes, and extension methods used by all other layers. API Project / Assembly:所有其他层使用的通用接口,枚举,类和扩展方法。 Need not be separate from Domain, but may. 不必与Domain分开,但可以。

  • Domain Project/Assembly: all entities and business logic. Domain项目/程序集:所有实体和业务逻辑。 Depends on API only. 仅取决于API Uses DDD patterns like factory, service, specification, repository, etc. Also contains more domain-specific interfaces which are not defined in the API. 使用工厂,服务,规范,存储库等DDD模式。还包含API中未定义的更多特定于域的接口。

  • Impl Project/Assembly: implementations of interfaces defined in API and Domain . Impl项目/程序集: APIDomain定义的接口的实现。 This is where the EF DbContext is implemented, as well as things like logging, email sending, etc. All of these implementations are dependency-injected, so technically you could have several Impl projects / assemblies. 在这里实现EF DbContext,以及日志记录,电子邮件发送等。所有这些实现都是依赖注入的,因此从技术上讲,您可以有多个Impl项目/程序集。

  • UI Project/Assembly: This is the MVC project. UI项目/程序集:这是MVC项目。 Controllers consume the domain surface directly, and do not go through an application or service layer. 控制器直接消耗域表面,并且不经过应用程序或服务层。 Any interface dependencies in factories, services, repositories, etc, are injected into the domain by the controller using MVC IoC (constructor injection). 控制器使用MVC IoC(构造函数注入)将工厂,服务,存储库等中的任何接口依赖项注入到域中。

I placed an API layer at the very core but you could combine the API and Domain projects into one. 我在最核心处放置了一个API层,但是您可以将API和Domain项目合并到一个。 Either way, the big meaty part of the onion is the Domain, and it has internal layering. 无论哪种方式,洋葱的大肉部分都是“领域”,并且具有内部分层。 For example Services may depend on Factories, which depend on Repositories, which depend on Entities. 例如,服务可能取决于工厂,而工厂取决于存储库,而存储库取决于实体。

The Impl project is what you see as the "Infrastructure" onion skin in Palermo's diagram. Impl项目就是您在巴勒莫图中看到的“基础结构”洋葱皮。 It is at the outer edge along with the UI, and contains no domain-specific knowledge. 它与UI一起位于外部边缘,并且不包含特定领域的知识。 It knows how to send email, store/retrieve data using EF, etc. If you want, you can have more than 1 of these -- for example 1 Impl for data access, 1 Impl for dealing with mail, etc. 它知道如何使用EF发送电子邮件,存储/检索数据,等等。如果需要,您可以使用其中的一种以上-例如,用于数据访问的1 Impl,用于处理邮件的1 Impl等。

MVC has the Controllers and Views, and concentrates on the UI and web application flow. MVC具有控制器和视图,并专注于UI和Web应用程序流。 Anything that requires domain-specific knowledge is delegated out to the domain, and domain classes are constructor injected into the controller. 任何需要特定领域知识的东西都被委派给该领域,并且将领域类作为构造函数注入到控制器中。 This means any constructor-injected interfaces in domain classes are resolved automatically by the IoC container. 这意味着IoC容器会自动解析域类中所有注入构造函数的接口。

As a final note, programming against interfaces defined in the API and Domain classes means you can unit test the domain project separately from the MVC project. 最后一点,针对在API和Domain类中定义的接口进行编程意味着您可以与MVC项目分开对单元项目进行单元测试。

From a high level, I'd describe it as layered architecture. 从高层次上讲,我将其描述为分层架构。 Describing it as domain-driven design would also look at smaller patterns like aggregate, repository, bounded contexts, etc. I can't tell just from your description. 将其描述为域驱动的设计还将关注较小的模式,例如聚合,存储库,有界上下文等。我不能仅从您的描述中看出来。

If the domain layer resides in an assembly/package that doesn't reference any of the others, then it has the core of the Onion Architecture principles , which are: 如果域层位于不引用其他任何层的程序集/程序包中,则它具有Onion Architecture原则的核心,即:

  • The application is built around an independent object model 该应用程序围绕独立的对象模型构建
  • Inner layers define interfaces. 内层定义接口。 Outer layers implement interfaces 外层实现接口
  • Direction of coupling is toward the center 耦合方向朝向中心
  • All application core code can be compiled and run separate from infrastructure 可以编译所有应用程序核心代码,并与基础结构分开运行

A concrete thing to look for is if your DataAccess references Domain. 要查找的具体内容是您的DataAccess是否引用Domain。

There could be different names depending from which angle you are looking at it. 根据您从哪个角度看,可能会有不同的名称。 So it's still MVC, it's just that your M is split into multiple layers. 所以它仍然是MVC,只是将您的M分为多个层。 It could also be called Multitier architecture (or N-tier architecture). 它也可以称为多层体系结构 (或N层体系结构)。 Jeffrey Palermo also used the notion of Onion architecture . Jeffrey Palermo还使用了洋葱架构的概念。

由于您已将DAL与域模型分开,并且还具有服务层,因此您似乎正朝着DDD(域驱动的设计)迈进,这里是有关这种方法的讨论,可能会很有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM