While learning domain driven design, I have been putting together the following solution (note that this ordering is lexicographic and not a representation of dependency):
Below is an outline of each project:
Domain.Models: Domain entities and value objects (e.g. Order)
Domain.Interfaces: Domain service interfaces and repository interfaces (e.g. IOrderService, IOrderRepository)
Domain.Services: Concrete implementations of domain services interfaces (e.g. OrderService)
Infrastructure.Data: Concrete implementations of repository interfaces (e.g. OrderRepository)
Infrastructure.DependencyResolution: Dependency injection resolution.
Problem
Now I would like to provide non-domain services. An example would be an email gateway for the sending of emails. I have created the following project for this:
Infrastructure.Components: Concrete implementations of non-domain services
Question
Where would I put the interfaces for such non-domain services (for example, an IEmailGateway)?
It would need to be accessible by the Domain.Services project (an OrderService might need you send out a notification), so would it go in Domain.Interfaces? I would say NO since sending an email is not a domain-specific activity.
I would say NO since sending an email is not a domain-specific
activity.
Sure, but you could get away by using a higher domain abstraction. The Domain doesn't care about emails but Notifications would be a perfect domain concept. It actually already seems to be part of the Ubiquitous Language, since you used that term in your question. So something along the lines of INotifier instead of IEmailGateway.
Alternate approaches could be :
Have the overarching Application Service send the email via an IEmailService interface defined in the Infrastructure.
Have the Order entity or domain service raise a Domain Event. An EmailService in the Infrastructure layer listens to it and sends the email.
If sending an email is not a concept of your bounded context then it means it's a part of another one. So you should apply some of the bounded contexts integration patterns such as anticorruption layer of domain events.
Whatever you choose I see another issue with your structure and solving that will eliminate the problem in the question. Try to structure your application in terms of bounded contexts and modules that use Ubiquitous Language rather then types of objects. So rather than Interfaces, Models and Services you should have Products, Clients, Shipments etc..
Related
I want to make an API using REST which interacts (stores) data in a database.
While I was reading some design patterns and I came across remote facade, and the book I was reading mentions that the role of this facade is to translate the course grained methods from the remote calls into fine grained local calls, and that it should not have any extra logic. As an explaination, it says that the program should still work without this facade.
Here's an example
Yet I have two questions:
Considering I also have a database, does it make sense to split the general call into specific calls for each attribute? Doesn't it make more sense to just have a general "get data" method that runs one query against the database and converts it into an usable object, to reduce the number of database calls? So instead of splitting the get address to get street, get city, get zip, make on db call for all that info.
With all this in mind, and, in my case using golang, how should the project be structured in terms of files and functions?
I will have the main file with all the endpoints from the REST API, calling the controllers that handle these requests.
I will have a set of files that define those controllers. Are these controllers the remote facade? Should those methods not have logic in that case, and just call the equivalent local methods?
Should the local methods call the database directly, or should they use some sort of helper class that accesses the database?
Assuming all questions are positive, does the following structure make sense?
Main
Controllers
Domain
Database helper
First and foremost, as Mike Amundsen has stated
Your data model is not your object model is not your resource model is not your affordance model
Jim Webber did say something very similar, that by implementing a REST architecture you have an integration model, in the form of the Web, which is governed by HTTP and the other being the domain model. Resources adept and project your domain model to the world, though there is no 1:1 mapping between the data in your database and the representations you send out. A typical REST system does have many more resources than you have DB entries in your domain model.
With that being said, it is hard to give concrete advice on how you should structure your project, especially in terms of a certain framework you want to use. In regards to Robert "Uncle Bob" C. Martin on looking at the code structure, it should tell you something about the intent of the application and not about the framework¹ you use. According to him Architecture is about intent. Though what you usually see is the default-structure imposed by a framework such as Maven, Ruby on Rails, ... For golang you should probably read through certain documentation or blogs which might or might not give you some ideas.
In terms of accessing the database you might either try to follow a micro-service architecture where each service maintains their own database or you attempt something like a distributed monolith that acts as one cohesive system and shares the database among all its parts. In case you scale to the broad and a couple of parallel services consume data, i.e. in case of a message broker, you might need a distributed lock and/or queue to guarantee that the data is not consumed by multiple instances at the same time.
What you should do, however, is design your data layer in a way that it does scale well. What many developers often forget or underestimate is the benefit they can gain from caching. Links are basically used on the Web to reference from one resource to an other and giving the relation some semantic context by the utilization of well-defined link-relation names. Link relations also allow a server to control its own namespace and change URIs as needed. But URIs are not only pointers to a resource a client can invoke but also keys for a cache. Caching can take place on multiple locations. On the server side to avoid costly calculations or look ups on the client side to avoid sending requests out in general or on intermediary hops which allow to take away pressure from heavily requested servers. Fielding made caching even a constraint that needs to be respected.
In regards to what attributes you should create queries for is totally dependent on the use case you attempt to depict. In case of the address example given it does make sense to return the address information all at once as the street or zip code is rarely queried on its own. If the address is part of some user or employee data it is more vague whether to return that information as part of the user or employee data or just as a link that should be queried on its own as part of a further request. What you return may also depend on the capabilities of the media-type client and your service agree upon (content-type negotiation).
If you implement something like a grouping for i.e. some football players and certain categories they belong to, such as their teams and whether they are offense or defense players, you might have a Team A resource that includes all of the players as embedded data. Within the DB you could have either an own table for teams and references to the respective player or the team could just be a column in the player table. We don't know and a client usually doesn't bother as well. From a design perspective you should however be aware of the benefits and consequences of including all the players at the same time in regards to providing links to the respective player or using a mixed approach of presenting some base data and a link to learn further details.
The latter approach is probably the most sensible way as this gives a client enough information to determine whether more detailed data is needed or not. If needed a simple GET request to the provided URI is enough, which might be served by a cache and thus never reach the actual server at all. The first approach has for sure the disadvantage that it doesn't reuse caching optimally and may return way more data then actually needed. The approach to include links only may not provide enough information forcing the client to perform a follow-up request to learn data about the team member. But as mentioned before, you as the service designer decide which URIs or queries are returned to the client and thus can design your system and data model accordingly.
In general what you do in a REST architecture is providing a client with choices. It is good practice to design the overall interaction flow as a state machine which is traversed through receiving requests and returning responses. As REST uses the same interaction model as the Web, it probably feels more natural to design the whole system as if you'd implement it for the Web and then apply the design to your REST system.
Whether controllers should contain business logic or not is primarily an opinionated question. As Jim Webber correctly stated, HTTP, which is the de-facto transport layer of REST, is an
application protocol whose application domain is the transfer of documents over a network. That is what HTTP does. It moves documents around. ... HTTP is an application protocol, but it is NOT YOUR application protocol.
He further points out that you have to narrow HTTP into a domain application protocol and trigger business activities as a side-effect of moving documents around the network. So, it's the side-effect of moving documents over the network that triggers your business logic. There is no straight rule whether to include business logic in your controller or not, but usually you try to keep the business logic in yet their own layer, i.e. as a service that you just invoke from within the controller. That allows to test the business logic without the need of the controller and thus without the need of a real HTTP request.
While this answer can't provide more detailed information, partly due to the broad nature of the question itself, I hope I could shed some light in what areas you should put in some thoughts and that your data model is not necessarily your resource or affordance model.
What is the difference between an SOA service and other kinds of services like an application or domain service ?
Have a look here. http://www.bennadel.com/blog/2385-application-services-vs-infrastructure-services-vs-domain-services.htm
Short answer
DDD Domain Services operate on Domain Entities. Usually where the work that needs to be done spans multiple Aggregate roots.
DDD Application Services drives workflow. For example if you want to do some work on a domain entity, the Application Service would be responsible to fetch the entity from the data store, call the domain service to do the work, do some work via an integration service if needed, and then lastly persist the change.
This is an interesting question since SOA is such as broad and overloaded term.
If we take SOA to mean any implementation that results in a mechanism to reach 'services' then even application and domain services will form part of SOA services. Application and domain services will even fall within the realm of micro-services although application services are usually surfaced through some integration mechanism.
I like to think of these things in terms of 'reachability'. WikiPedia:
In graph theory, reachability refers to the ability to get from one vertex to another within a graph
So, it depends on how reachable your code is. A bunch of domain services could, theoretically, form a service-oriented architecture.
The only differences is in how you surface your services.
We have started our projects with DDD design principles, I heard that any business logic needs two or more domain objects interaction should be written as domain services.
My question is:
Since my business logic includes saving of more than one domain or access many domain objects for validation purpose, can I pass repository inside the service method or can I access using DIContainer.
In case of operation A I will build List<Specification> (Specification classes which contain validation) and pass on to domain services from application layer. So my domain service validates and does business logic.
Can domain service use CRUD operation in itself.
I am really confused where to draw a line between application service and domain service.
Can I get any good samples which has application services, domain services, domain specifications with repositories involved.
Answer is here: http://gorodinski.com/blog/2012/04/14/services-in-domain-driven-design-ddd/
Actually these rules apply:
1) domain entities do the job
2) if in some function more entities are involved, changed - a domain service may be the solution
3) no, domain layer should not know anything about: transaction, saving, locking, etc. neither should load entities... if you need something like that use INeedSomeStuffFromRepo. Interface is defined in the domain layer, implementation is inside app. services. This way you could also doi locking, f.e. IExecuteThisFncToLockBeforeManipulatingWithAnObject
4) saving, transaction is in the app service side. i use persistence by reachability, so even if i have an aggregate, entity with other entities related, it's enough to save the parent...
Domain service actually is the Pure fabrication in GRASP. everything does not fit in an entity or a value object.
I am bit confused about services in DDD.
First of all. Why are services always expressed as an Interface? Is that a rule?
Why do services contain only one method? Sometimes it makes sense to implement related methods in a single class.
Do I have to make services for each repository? I must be doing something wrong because I find myself making services for CRUD operations.
For example I have a repository with the usual methods. How do I control the access to the objects persisted in the repository? I tend to make services with lots of reading methods. Those services can check the user roles and then decide if the user can use the objects or not. I feel something is not good in my design.
I'm assuming you're talking about domain services. There are other types of services in DDD such as application services and infrastructure services.
First of all. Why are services always expressed as an Interface? Is
that a rule?
No this is not a rule. Only create an interface abstraction when there is a need for it.
Why do services contain only one method? Sometimes it makes sense to
implement related methods in a single class.
A service with a single method can be thought of as implementing a single operation - a single use case. If it makes sense to encapsulate multiple operations in a single object than this is also acceptable. However, conflating multiple responsibilities into a single class often leads to violation of SRP.
Do I have to make services for each repository?
No. A repository is already a sort of service. More specifically, a repository implementation can be thought of as an infrastructure service.
It is the application service which calls a repository in order to implement some use case. It delegates to domain entities and orchestrates other services that may be required for a given operation. Take a look at Services in DDD for an example of the various services interacting.
about a year ago I set set up a solution consisting of an ASP.Net MVC 3 (now) presentation layer, application layer, domain layer and infrastructure layer (crosscutting stuff and data). I decided to keep the domain model in a separate project from the domain logic and use a relaxed approach to the presentation layer by passing the domain entities instead of DTO's since we really only have 1 front end right now.
We are going to be servicing a distributed layer soon, in addition to our main website and I will use DTO's there, but I am considering using DTO's in the main website also. I am also wondering if I should bother to break out the framework code in the domain layer (IRepository, IUnitOfWork, Entity/Value object supertypes etc). Well here, let me list out the questions I need feedback on:
1) I was pretty diligent about not having an anemic domain model and also watched out for behavior that was specific to the presentation concerns. Most of the business calculations that are needed are on the domain entities, is it ok for the presentation layer to call this behavior directly or should it instead call an application service that then calls the domain entities? This would suggest to me that there is no reason to have the presentation layer know about the domain entities and instead could use DTO's. Alternatively, I could have the DTO's expose these behaviors, but then I feel like I am robbing the domain entities. So I guess that is 3 options (Rich domain objects called directly, service layer or dto with behavior) which is best?
2) Right now I have a domain project, which has domain services, specifications and logic and is orchestrated by the application layer and separate project for the domain model (used by presentation layer and application layer). I also have framework interfaces for generic repository and unit of work pattern here. Should I break the framework stuff out into a separate project and combine the rest into one project?
3) I want to reorganize my domain layer into aggregates, right now all of the domain model is organized by modules, basically all the types for each module are in one namespace. Would it be better to organize the entities, value objects, services and other stuff by the aggregates?
4) Should I use the Separated Interface pattern for infrastructure services that are basically .net framework helper library types? For example configuration objects or validation runners? What is the benefit there in doing so?
5) Lastly, not many examples I have seen have used interfaces for domain entities. Almost every object I have I prefer to pass around interfaces for dependency reasons and it makes testing much easier. Is it valid to use interfaces instead of concretes? I should mention that we use EF 4.3.1 (soon to upgrade to latest version) and I seem to remember that EF had a problem with using interfaces or something. Should I be exposing interfaces instead of the domain entities?
Thank you very much in advance.
Project Structure:
Presentation.Web
| |
| Application
| | |
Domain.Model - Domain
(Infrastructure.Data, Infrastructure.Core, Infrastructure.Security)
Explanation:
Presentation.Web (MVC3 Web Project)
Application
-- Service Layer that orchestrates the domain layer and responds to requests from the presentation layer (get this update that). This is organized by module, for example if I had a customer module I would have Application.Customer and in that would be all of the application services
Domain
-- Contains domain services, specifications, calculations and other domain logic that is not exposed as behavior on domain entities. For example a calculation that involves several domain entities exposed as a domain service for the application layer to call.
-- Also contains framework code for a specification framework and the main interfaces for a generic repository and unit of work pattern.
Domain.Model
-- Contains the domain entities and enumerations. Organized by module. For example, if I might have a customer module which has a customer entity, customerorder entity etc. This is broken out away from the domain project so that the objects can be used by the application and presenation layer.
Infrastructure.Security
-- Security infrastructure for authentication and authorization
Infrastructure.Core
-- Cross-cutting stuff used by multiple layers (validators, logging, configuration, extensions, IoC, email etc..). Most of the projects depend on interfaces in this project (except domain.model) for infrastructure services.
Infrastructure.Data
-- Repository Implementations via LINQ and EF 4.3.1, mapping layer, Unit of Work implementation. Interfaces are in Domain project (separated interfaces pattern)
1) First, determine whether your main website really needs to use the application layer. IMHO, if your application services and your main website are on the same web server, then you should evaluate whether the potential performance loss is worth having your main website call app server methods when it could call the domain objects directly. However, if your application server is definitely on another server, then yes, you should have the application server call your domain objects and pass only DTOs back and forth between it and any presentation layers you may have, including your main website.
2) This is really a question on preference of organization. Both are valid. You choose.
3) Anoter question on preference of organization. I, personally, organize my code by bounded context first. Then, I have entities and aggregate roots directly under them. Then, I have folders for Enumerations, Repositories (interfaces), Services (interfaces), Specifications, and Values. The namespaces do not reflect this organizational structure past the last bounded context folder. But, again, you should do this in the way that best suits the way you look at the code.
4) This is an implementation concern. I, personally, only break out implementation concerns into interfaces if I think there is a good possibility that I will need to swap out the implementations in the future. That being said, I usually organize my helper libraries into specific infrastructure contexts (eg. MainContext.Web.MVC.Helpers or MainContext.Web.WebForms.Helpers.) These rarely change and I have yet to come across an instance where I needed to swap out implementations entirely.
5) From my understanding, it is perfectly valid to use interfaces instead of concretes for your domain entities. That being said, I have yet to run into a case where I needed different implementations for my domain entities. The only reason I can even think of would be if you needed to change your business logic for one application, but leave an older application using the original business logic. If your business objects are good models for the domain, I can't fathom you actually running into this problem, but I have seen examples where people do this just for the sake of the abstraction. IMHO, that is not worth the extra coding effort, but if it makes you feel good inside or you get some actual benefit (eg. making testing easier), there isn't any reason why you can't abstract out your domain entities. That being said, domain services and repositories should definitely have contracts that allows you to swap out their implementations.
Answer 5 is derived from the idea that the application is the one who chooses the implementations. If you are trying to achieve onion architecture, then your application is going to be choosing the concrete implementations for everything (repositories, domain services, and other abstracted implementation concerns). I see no reason why it can't just use domain aggregates directly since they are the concrete representation of your domain model. (Note: All entities should be encapsulated into aggregates. The application should never be able to hold a reference to an entity that is not an aggregate under the context)