简体   繁体   中英

Which layer is responsible for the business logic?

I am working on a project that designed base on Domain Driven Design.

In this project, we have 5 layers:

  1. Infrastructure
  2. Domain
  3. Application Service
  4. Distributed Service
  5. Presentation

I am confused about how to put my business logic among Infrastructure, Domain and Service layers. Sometimes I put the business logic condition in iqueryable Linq in a repository; sometimes I load all the objects to memory and put them into services; and sometimes I put them in the method of an object. I don't know which way is the right way. Which layer should be responsible for this business logic?

I need some concrete reasons to convince a team of developers that business logic in code is better, because it's more maintainable. I used to have a lot of business logic in the DB, because I believed it was the single point of access.

Stored procedure are usefull to speedup certain DB operations. Stored procedure are evil because:

  • it's hard to versioning (not the hardest thing, but harder than versioning your project)
  • it's harder to deploy (eg in my job we have thousand of DBs with thousand of stored procedure's on a couple of servers; when we change logic of a SP we have to update every DB: a pain in the neck.)
  • it's difficult to debug,
  • it's difficult to unit test

Said that... implementation of repositories are infrastracture, and infrastracture doesn't know about domain and business logic. After all I can't really see DDD in this question, maybe you should deepen concepts like entity, value object and aggregate root, together with repository and domain model.

The only thing that we can confirm right now is: Business logic intended as domain logic belongs to the domain model/domain layer. The domain logic is rules that act always in the same way apart from the use case (eg: if the order is more expensive than 100$ the shipment is free). If you have a rule that depends on a use case (eg: if a user browse my e-commerce with the appmobile than ...) this is application logic.

DDD 还遵循“关注点分离”规则,因此围绕域的业务留在域层中,如果域外的某些东西是依赖的,那么我们将它们放在更高的层中,例如表示层中的模型视图。

I know this is old, but I've had some experience working on older projects where the database held all the logic and various systems used that logic. Updating any of those systems became a nightmare of making a change to any of it would break something somewhere else.

DDD was built to get around these exact scenarios.

Think of it as you having one focused application that controls it's domain, defining the domain is often hard, but lets say you could define a traditional system with 3 domains.

Commerce Domain controls how to take orders.

Logistics Domain controls how to ship orders.

Billing Domain for how orders are paid for.

Each one of these domains would ideally be represented layered applications, but the whole end to end story of an "order" involves all 3 applications. Each domain controls it's business and is responsible for doing it's job the best way it can.

Billing Domain could be as simple as a web api that appends order data to a csv file that someone in accounting opens once a month and hand types an invoice out. Or it could grow into a massive complex beast of quickbooks integrations automatically pulling money from saved accounts. The Commerce and Logistics domain shouldn't have to care about where the billing domain is saving it's data or how they're getting paid. They just have the responsibility to inform the billing domain when something is sold and when something is shipped.

The Commerce domain likewise shouldn't have to care about how shipping costs are calculated, it just needs to ask the Logistics domain. Commerce shouldn't be rooting around in a database that Logistics needs, becasuse then if Logistics wants to pivot and use google maps to determine shipping costs we'll need to update Commerce then as well.

Once you understand the concept of "Every domain controls it's data, if you need that domains data, you ask that domain." The next bits kinda fall in line.

Each domain will have a Presentation Layer or two, this can be a website, api, mobile/desktop app or a combination of the above. Each domain will have business logic in a domain/application layer. Each domain will be supported by infrastructure like databases and apis.

In the above example we could have a Commerce Domain. It's presentation layer renders a website to a user, it's domain layer is composed of OrderPage and interfaces for commands/queries. It's infrastructure layer has logic to handle those commands and queries, most of them probably go to a private database, but we also have some api calls out to the Logistics and Billing domains.

Our Billing Domain has 2 projects in it's presentation layer. One is an API that's used to field requests from the Commerce and Logistics domains, the other is a desktop app that we wrote for accounting. They both talk to the same domain objects/interfaces so if accounting needs to log in and manually modify an order, they can do so just as easily as if it was happening on the website. The interfaces in the domain are implemented by the infrastructure which could be a quickbooks api which will also forward data into freshbooks until that big migration is finished. No code in Commerce and Logistics has to care about freshbooks/quickbooks, and we can use both at the same time if we want to.

Our Logicstics domain similarly has two projects in it's presentation layer. A console app that runs on a scheduled task once a morning to batch up orders and an api. Same deal with it's data.

Ok that got a bit too long and I'm going to wrap that up. No one will probably read this answer on a 4 year old post anyways lol.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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