This doesn't sound like DDD
There isn't much in your question which talks about your Domain Model. You mentioned an "Employee getting added to a system and a Salesforce", but outside of that I have no real sense of what your application is intended to do, in a business sense. My understanding of an "Employee" and a "Salesforce" are based on familiarity with the words, not on explication of their models in your system.
I don't really have a sense of what an "Order Application Service" is supposed to represent in terms of your model. I get an "Order" and "Order Notification". It seems like a "Customer" makes an "Order", and some "Subscriber" gets "Notified", but a lot of this is based on my prior knowledge of design patterns.
You should be able to describe the business domain model as it would work if computers didn't exist. If you need a computer term to explain the idea, it is probably mixing in something that is extrinsic from the model.
Obviously, you need to integrate the application logic with your domain logic, but this should not entail confusing your concerns. However, there are ways around this.
How you can fix it
- You can use interfaces instead of implementation specific classes to model services in your domain layer. This is known as the interface segregation principle. It makes sense that part of your model includes notifying the responsible employee when a customer places an order. However, there isn't necessarily any reason that the implementation of this notification should be coupled to its modeled purpose. There could be a supervisor making an announcement over an intercom in a crowded office or there could be an email being sent by an automated system. Both of these examples serve the same business purpose. Instead of embedding an email service in your domain layer you can have an
IOrderNotificationService
interface that simply contains a method void NotifyOrderReceived(Order order);
. That way you have all of the business logic that you need in your domain layer without introducing unnecessary concerns like an "Email" implementation, or persistence to a database. I am guessing at this, but your OrderNotificationService
and OrderApplicationService
are really responses to the same event, but one has a database dependency and the other has an SMTP dependency. Both are infrastructure concerns.
Coding against a single interface will be sufficient in many cases. However, there is a problem that your domain objects now have a dependency on an injected service or a global variable. Also, this might indicate that these entities know too much about their dependency. A customer might not need to know the inner workings of how an order gets processed, but only that it was processed and they will receive what they ordered. Similarly, an Employee probably doesn't add himself to a Salesforce, because he doesn't know about it prior to becoming an Employee. All he knows is he just got a job.
There is a very good solution to this problem...
You can use a "Domain Event" pattern. The basic idea is that the domain objects only know what just happened and how their state has been changed, but don't need to know anything about persisting or propagating that altered state. They handle their internal logic and then raise a "Domain Event". This is more similar to a Customer placing an Order and then yelling "Yo, I ordered this product!" or an Employee getting hired and then yelling, "Yo, I got a job!". Taking this approach will greatly simplify your domain logic and allow you to achieve a much cleaner separation of concerns. Udi Dahan has an excellent series of blog posts in which he explains both the logic behind leveraging the Domain Event pattern and provides a very simple but very effective implementation. Here are some links:
Now, in case you're the type of developer who likes to copy and paste code before fully understanding it, I suggest you start with the third of these posts. They document an evolution in Udi Dahan's thinking and experience with the pattern. The most sound code sample appears in the third article. Ideally, you would read all three, in order, so that you can follow his logic and actually understand how you can benefit from his approach and why it accurately represents "Domain Driven Design".
As added justification to the "Domain Event pattern", Eric Evans' 2009 review of what he had learned about Domain Driven Design since writing his groundbreaking book made a point that Domain Events were a significantly overlooked core building block in his book. An summary of his talk is available here, and links to the presentation are available here.
A few other resources that might help you successfully apply this pattern include Jimmy Bogard's article Strengthening your Domain: Domain Events and Martin Fowler's Domain Event article. Bogard has links to other helpful DDD blog posts from the referenced link.
In general,
If you really want to try applying domain driven design, you will be much more successful by getting a real understanding of what you are modeling and what you are implementing for what purpose. There is no implicit value in simply using a terminology that you are unfamiliar with and labeling your code as such. DDD can be extraordinarily helpful, but if you don't take the time to understand why you are making the distinctions and design decisions, you will end up with a lot of unnecessary abstractions and general confusion.
OrderApplicationService
? – smartcaveman