Can anybody have good answer when should be database driven development be used and when should domain driven development be used. These both development approach have their importance in their respected areas. But I am not so clear which approach is appropriate in what type of situation. Any recommendation?
When to use domain driven development and database driven development?
domain-driven-design
Related Solutions
But what is not clear to me is where the factory "layer" lies with a DDD architecture? Should the factory be calling directly into the repository to get its data or the service library?
The factory should be the one-stop shop to construct domain objects. Any other part of the code that needs to do this should use the factory.
Typically, there are at least three sources of data that are used as input into a factory for domain object construction: input from the UI, the results of queries from persistence, and domain-meaningful requests. So to answer your specific question, the repository would use the factory.
Here is an example. I am using Holub's Builder pattern here. Edit: disregard the use of this pattern. I've started realizing that it doesn't mix too well with DDD factories.
// domain layer
class Order
{
private Integer ID;
private Customer owner;
private List<Product> ordered;
// can't be null, needs complicated rules to initialize
private Product featured;
// can't be null, needs complicated rules to initialize, not part of Order aggregate
private Itinerary schedule;
void importFrom(Importer importer) { ... }
void exportTo(Exporter exporter) { ... }
... insert business logic methods here ...
interface Importer
{
Integer importID();
Customer importOwner();
Product importOrdered();
}
interface Exporter
{
void exportID(Integer id);
void exportOwner(Customer owner);
void exportOrdered(Product ordered);
}
}
// domain layer
interface OrderEntryScreenExport { ... }
// UI
class UIScreen
{
public UIScreen(OrderEntryDTO dto) { ... }
}
// App Layer
class OrderEntryDTO implements OrderEntryScreenExport { ... }
Here is what the OrderFactory might look like:
interface OrderFactory
{
Order createWith(Customer owner, Product ordered);
Order createFrom(OrderEntryScreenExport to);
Order createFrom(List<String> resultSets);
}
The logic for the featured Product and the generation of the Itinerary go in the OrderFactory.
Now here is how the factory might be used in each instance.
In OrderRepository:
public List<Order> findAllMatching(Criteria someCriteria)
{
ResultSet rcds = this.db.execFindOrdersQueryWith(someCriteria.toString());
List<List<String>> results = convertToStringList(rcds);
List<Order> returnList = new ArrayList<Order>();
for(List<String> row : results)
returnList.add(this.orderFactory.createFrom(row));
return returnList;
}
In your application layer:
public void submitOrder(OrderEntryDTO dto)
{
Order toBeSubmitted = this.orderFactory.createFrom(dto);
this.orderRepo.add(toBeSubmitted);
// do other stuff, raise events, etc
}
Within your domain layer, a unit test perhaps:
Customer carl = customerRepo.findByName("Carl");
List<Product> weapons = productRepo.findAllByName("Ruger P-95 9mm");
Order weaponsForCarl = orderFactory.createWith(carl, weapons);
weaponsForCarl.place();
assertTrue(weaponsForCarl.isPlaced());
assertTrue(weaponsForCarl.hasSpecialShippingNeeds());
Where does the factory fit into the following framework: UI > App > Domain > Service > Data
Domain.
Also, because the factory is the only place allowed for object creation would'nt you get circular references if you wanted to create your objects in your data and service layers?
In my example, all dependencies flow from top to bottom. I used the Dependency Inversion Principle (PDF link) to avoid the problem you speak of.
If the role of the factory class is for object creation then what benefits does the service layer have?
When you have logic that doesn't fit into any single domain object OR you have an algorithm that involves orchestrating multiple domain objects, use a service. The service would encapsulate any logic that doesn't fit in anything else and delegate to domain objects where it does fit.
In the example I scribbled here, I imagine that coming up with an Itinerary for the Order would involve multiple domain objects. The OrderFactory could delegate to such a service.
BTW, the hierarchy you described should probably be UI > App > Domain Services > Domain > Infrastructure (Data)
I've asked a lot of questions and appreciate any response. What i'am lacking is a sample application which demonstrates how all the layers in a domain driven design project come together...Is there anything out there?
Applying Domain Driven Design and Patterns by Jimmy Nilsson is a great compliment to Eric Evans' Domain-Driven Design. It has lots of code examples, though I don't know if there is an emphasis on layering. Layering can be tricky and is almost a topic separate from DDD.
In the Evans book, there is a very small example of layering you might want to check out. Layering is an enterprise pattern, and Martin Fowler wrote Patterns of Enterprise Application Architecture, which you might find useful too.
Services come in 3 flavours: Domain Services, Application Services, and Infrastructure Services.
- Domain Services : Encapsulates business logic that doesn't naturally fit within a domain object, and are NOT typical CRUD operations – those would belong to a Repository.
- Application Services : Used by external consumers to talk to your system (think Web Services). If consumers need access to CRUD operations, they would be exposed here.
- Infrastructure Services : Used to abstract technical concerns (e.g. MSMQ, email provider, etc).
Keeping Domain Services along with your Domain Objects is sensible – they are all focused on domain logic. And yes, you can inject Repositories into your Services.
Application Services will typically use both Domain Services and Repositories to deal with external requests.
Hope that helps!
Best Solution
First for some background, Martin Fowler actually described three different "patterns" in his book Patterns of Enterprise Arcitecture. Transaction Script, Active Record and Domain Model. DDD uses the domain model pattern for the overall architecture and describes a lot of practices and patterns to implement and design this model.
Transaction script is an architecture where you don't have any layering. The same piece of code reads/writes the database, processes the data and handles the user interface.
Active Record is one step up from that. You split off your UI, your business logic and data layer still live together in active record objects that are modeled after the database.
A domain model decouples the business logic that lives in your model from your data-layer. The model knows nothing about the database.
And now we come to the interesting part:
The cost of this added separation is of course extra work. The benefits are better maintainability and flexibility.
Transaction script is good when you have few or no business rules, you just want to do data-entry and have no verification steps or all the verification is implemented in the database.
Active record adds some flexibility to that. Because you decouple your UI you can for example reuse the layer beneath it between applications, you can easilly add some business rules and verification logic to the business objects. But because these are still tightly coupled to the database changes in the datamodel can be very expensive.
You use a domain model when you want to decouple your business logic from the database. This enables you to handle changing requirements easier. Domain Driven Design is a method to optimally use this added flexibility to implement complex solutions without being tied to a database implementation.
Lots of tooling makes data-driven solutions easier. In the microsoft space it is very easy to visually design websites where all the code lives right behind the web-page. This is a typical transaction script solution and this is great to easilly create simple applications. Ruby on rails has tools that make working with active record objects easier. This might be a reason to go data-driven when you need to develop simpler solutions. For applications where behaviour is more important than data and it's hard to define all the behaviour up front DDD is the way to go.