DevTeach 2007 -- Complex Business Rules with DDD and O/R Mapping (Udi Dahan)

Complexity kills

There are problems that technology, no matter how new, will not solve.

Scalability isn’t always about hardware.  It could be about scaling the size of the developer team.

Elegance is recognized on sight.

What’s a business rule?  If <x> then do <y>

Complexity arises from the fact that we have a lot of intertwining business rules.  Almost like a house of cards, you remove one rule and some or all of the others start to collapse.

Encapsulation is the answer.

Domain Model Pattern.  The DM is isolated and each component works with properties, methods and events.  Properties are usually readonly.  Change data through methods.  Let things be known through the events.

Domain models by definition are independent of things like UI, database and communications.

More and more logic in a DM increases the complexity of the testing.

Where do the rules get implemented in a 3 tier system? 

  • SPs?  Not easily, or nicely.  In the DAL?  No.  In the Business Entity?  No, it’s just data. * Business Components?  They don’t have the data though.  Where would string validation occur?  In the BE or the BC?

Making changes to complex business logic in this scenario makes it hard to have confidence that your changes aren’t breaking anything.

Customers and Orders is a good example for complex business logic.  So many possibilities.

Denormalization of a DB is a fact of life.  It can, as a side effect, eliminate some of the complexity from the business rules.

Denormalizing your code will happen too.  Lazy loading is scary because it can result in one developer bringing the system to it’s knees.

Domains are split into projects (i.e. CustomerDomain and OrderDomain).  What would this do to your project count on a large system?  I can’t see this being sustainable, although it will reduce developer code changing concurrency.

Another sales pitch on coding to the interface (even testing).  Look people, I already bought the store out of this!

Represent each scenario with an interface.  The interface can be used to restrict what the developer can do.  You can check that the coding to the interface exists, but it’s hard to check if a developer has coded a method or not.  Restrict this possibility though the items exposed by the interface.

Using events in your DM can allow you to better separate the concerns.

Persistence by Reachability (not supported by nHibernate, Vanatec does.).  This is the ability for the ORM to cascade update or save the child objects when you save or update the top level object.  This is a big deal in the amount of code that you will write in the service layer.

Keep logic out of the service layer.  Separation of Concerns says that the service layer deals with transactions and database calls, not the logic.

IEnumerable is good.  Doing ICustomer.Orders.Add(blah) is the equivalent of saying ”Hey you look hungry, let me open you up and stick a burger in your stomach”.

Decorator is layering behaviour on myself to provide different functionality.

DM is not work doing if you have only 5 business rules.  Allows you to manage the complexity of a large number of rules.

Switching the object is not easy.  Decorator pattern gives you a lot of problems with persistence.

DM without TDD is useless.  You need tests or you end up with the same mess as if you hadn’t done the DM.

Interfaces allow you to explicitly define your scenario and pass that knowledge on to your domain model.