| 
  • If you are citizen of an European Union member nation, you may not use this service unless you are at least 16 years old.

  • Work with all your cloud files (Drive, Dropbox, and Slack and Gmail attachments) and documents (Google Docs, Sheets, and Notion) in one place. Try Dokkio (from the makers of PBworks) for free. Now available on the web, Mac, Windows, and as a Chrome extension!

View
 

DDD is for CRUD Apps

Page history last edited by Ward Bell 13 years, 3 months ago

When confronted with a brown-field application development scenario I often find myself in the camp that finds value in leveraging an existing database schema during the development of my domain model. By "leveraging" I mean that I construct some part of my domain model with the aid of an ORM tool that takes the database schema as one of its inputs and produces a conceptual model as one of its outputs. I am pleased to use that conceptual model to generate a portion of my domain model.

 

For some this approach is anathema. One expression of revulsion is to dismiss the tool and approach as suitable only for CRUD applications. Apparently a CRUD app is pretty low on the sophistication scale. I am often told that if this is "all" I'm going to do (read: all that I am capable of), I should stick to one of the less intellectually challenging design patterns, maybe ACTIVE RECORD, and leave OBJECT MAPPER and DOMAIN MODEL to the big thinkers.

 

It follows also, they would suggest, that this so-called "Data First" approach betrays an almost constitutional ignorance of modern design patterns and practices and is utterly incompatible with Domain Driven Design (DDD). I think this leap to judgment, while understandable, is unwarranted and prematurely terminates what could be productive discussions.

 

In this page I will hold that

  • DDD is almost invariably demonstrated with a CRUD application
  • Data-firsters build behavior rich Domain Models too
  • Ease of code generation undermines thought
  • The real question is "do you engage your design faculties or not?"
  • Data-first can assist DDD
  • DDD and "Data First" are compatible when the "Data Firster" uses his or her head

 

DDD for CRUD

 

Jimmy Nilsson shows us DDD in action in his highly regarded book, Applying Domain-Driven Design and Patterns [ADDP] by stepping through the design and development process of an application with the following requirements:

 

  1. List customers by applying a flexible and complex filter
  2. List the orders when looking at a specific customer
  3. An order can have many different lines
  4. Concurrency conflict detection is important
  5. A customer may not owe us more than a certain amount of money
  6. An order may not have a total value greater than a predetermined system-wide order limit
  7. Each order and customer should have a unique and user-friendly number
  8. A new customer is acceptable only after passing a credit check by an independent institution
  9. An order must have a customer; an order line must have an order
  10. Saving an order and its lines should be atomic
  11. Orders have an acceptance status that is changed by the user

 

This is a classic CRUD application. It is, in words typically uttered with total derision, "just a CRUD app."

 

It is also the richest investigation of DDD development that I have found. Jimmy devotes nearly half of the 500 pages of his book to this example. I have yet to see an example of DDD in practice that is as thorough as this one.

 

This is the only example in Jimmy's. He never even hints that this CRUD app is inadequate to the task of demonstrating DDD. It is all he requires to show DDD's superiority relative to the way he used to build applications. Yes, the app is a toy and half-baked - as it must be for purposes of exposition. But it does what he wants it to do pedagogically.

 

I'm not trying to make Jimmy a saint or sinner. This post is not about Jimmy.

 

I do intend to make it hard for someone to say, "well, that's just a CRUD example and DDD is for more sophisticated applications." I figure if Jimmy wrote the app with DDD, it's a DDD app. If Jimmy thought we should use ACTIVE RECORD instead of Domain Model, he would say so.

 

I am also trying to discover if there is something distinctly different about applications that people are building with DDD. On the strength of this example, we all seem to be building the same kind of apps.

 

Are so-called "object first" applications somehow beyond the reach of applications developed when you use "data first" techniques? Is there something Jimmy is doing here that we aren't doing routinely ourselves? Not that I can tell.

 

We Build Behavior Rich Domain Models Too

 

A subset of Jimmy's application's requirements are manifestly "behavioral"

  • Concurrency conflict detection is important
  • A customer may not owe us more than a certain amount of money
  • An order may not have a total value greater than a predetermined system-wide order limit
  • Each order and customer should have a unique and user-friendly number
  • A new customer is acceptable only after passing a credit check by an independent institution
  • Saving an order and its lines should be atomic
  • Orders have an acceptance status that is changed by the user

 

Guess what? You will find implementations for such requirement in my "data first" applications. These kinds of requirements are routine for us as well.

 

Look closer at my own applications and you will see Aggregates, Value Objects, Services, Repositories, Unit-of-Work, inheritance, etc.. You'll see Dependency Injection and MVC/MVP too. I can't say that I have always been as clear and decisive with the purely DDD structures; I'm new to the DDD formalisms although one of the reasons it resonates so strongly with me is that (as with the GoF patterns) there is a shock of recognition when you first seem them - the realization that DDD captures what you should have been doing - and were sort of doing - all along.

 

It certainly seems to me that I approach these needs with the same attitude and catalog of "solutions" as any "object-first" architect. I just happened to get there with my "data-first" tools. And I didn't have to stand on my head or otherwise fight my own tools or predilections to do so.

 

Let's take "behavior" for example. Someone is always trying to tell me that "data firsters" don't understand the difference between data objects and objects with behavior.

 

There is some strange misconception, widely repeated, that "data firster" business objects lack behavior; that they are just stupid property bags straight from the ORM code generator. Where does this notion come from? Every generated domain object class file is paired with a custom class file. That's where we put our behaviors. We are going to enrich our domain model in order to satisfy the expectations coming from the business and we're going to do it in that custom class. Go ahead and decry the noise and alleged confusion that I must be experiencing because I have two class files to do the work of your single file (psst - I hardly notice). But why insist that I'm not writing behavior at all?

 

When I look at Jimmy's classes - the ones he actually wrote - I don't see any important differences between what his code does and what my code does. You will find no less behavior in one of my business object classes than in one of Jimmy's classes.

 

Yes there are differences - we won't write the same code. But once you set aside the code gen and Persistence Awareness artifacts, what is left of genuine substance to fight about?

 

I must be quick to acknowledge that there are characteristic misbehaviors with the "data-first", code-generation approach that always show up in the code. Every technique is prone to its "signature" mistakes - the kinds of mistakes that are so easy to make that they always leave evidence behind. We'll talk about some of these shortly. But they are minor sins, easily expiated.

 

My point, in this section, is that, from the perspective of a consumer of the Domain Model, there is no fundamental reason for Data-firsters to produce a domain model that is appreciably different from the one produced by an Object-firster.

 

There are some differences in how we got to a given place. There are some differences in how we pursue development in subsequent iterations. But if we both consistently produce a domain model that delivers the same capabilities, with similar APIs, in a similar amount of time, with comparable quality, ... iteration after iteration ... then I cannot see why one camp must lord it over the other.

 

The burden of proof falls on he who would claim that we cannot achieve comparable outcomes.

 

What About Those Getters and Setters?

 

There is a faction within the DDD family that is at war with getters and setters in Domain Model classes. I think they make important points. I also think they over-state the benefits and understate the challenges of doing without getters and setters. Challenges begin in earnest when you have to present domain objects in the UI. If we are to move state between a domain object and widgets on the screens, with today's client technologies one is driven to writing intermediaries (e.g., DTOs) that actually do have properties . For a glimpse of the tedious care and feeding such intermediaries require, see Mats Helander's article in Jimmy's book [p.431]

 

Aside: this has nothing to do with separated presentation per se. If domain model objects are property-less, the "Model" -  in MVC or MVP or embedded in a Presentation Model - can not consist of domain model objects; there must be intermediaries. Perhaps this is a virtue but it is won at hard cost.

 

If you believe getters and setters are bad, you will really hate the "data-first" ORM approach which emits properties in great abundance. Property generation is the strength of the "data-first" style. It is its strength ... and its weakness.

 

Before I pursue that thought, I must observe that the "no properties" faction appears to be a minority within DDD. Maybe Jimmy's example application is "old-school" DDD - it's so "2006" - but his domain model classes have plenty of properties and his associates, who build the UI on his domain models, are not shy about working directly with those domain objects and their properties. So I don't think DDD'ers are united in hating properties.

 

But the property resisters have a great point. DDD stresses the importance of designing and implementing in the language - the ubiquitous language (UL) - of the business domain. If "Get LastName" and "Change LastName" are sensible operations in the UL, the properties belong. But if "ShoeSize" is not a meaningful fact about a person in the UL, we should not have a ShoeSize property.

Data-firsters have the bad habit of acting as if every column in every table is directly expressible in the UL as a "get" and "set" operation. In other words, we have a tendency to expose every column as a property. It's just so easy to do.

 

The same is true for bi-directional relationships. Order.Customer? Customer.Orders? The ORM can generate them both; let 'er rip.

Again, it's so easy ... that we let the ORM generate these properties ... and now our domain model has unwanted behavior that clouds our vision, adds a point of failure, and consumes testing resources.

 

There is something insidious in this too. Our ubiquitous language may support setting the Last Name. But not necessarily at will. Not necessarily in isolation from other domain model state or rules. By blithely spitting out a LastName property, we gloss over the careful analysis that should have gone into the decision to expose a mutator of this value.

 

Do You Design Or Not

 

Let me stipulate: blind "data-first" thinking combined with rapid code generation is a formula for poor design.

 

I know the perverse delight in spewing a "model" of 100 table-backed-classes in fifteen minutes. I suppose this is like firing off a few thousand rounds from an assault rifle. Kind of cool on the range; not very cool if I do the same thing at ... I don't know, let's pick on the poor post office again.

 

Is it the tool's fault? Or is it my fault?

 

If I use the ORM this way, shame on me. I didn't have to.

 

I may have to cope with the fact that the legacy ShoeSize column is in my Person table ... and I am not allowed to get rid of it. But I don't have to expose ShoeSize publicly as a property. I don't have to expose both sides of a relation. And, if there is special business logic governing how to change LastName, I can bury the property and write a "message" method to mutate it properly.

 

In short, if I just fire up the ORM and pull the trigger, does my tool make me an idiot? Or am I an idiot to begin with.

 

When Data-First Improves Design

 

A significant portion of Evans seminal DDD book concerns how you determine what the domain model should be; how you align it with the business. The message, repeated in many forms, is "this is very hard."

 

If you've been a consultant, you know that learning your customer's requirements is wickedly difficult both because she isn't sure what she wants and because you don't understand her business well enough to understand her even if she explained it well.

You have to play anthropologist. An apologist listens to stories, yes, but he also looks at actual behavior and, in particular, the artifacts of the culture he studies.

 

I suggest that an existing database is one of your most important sources of insight into the culture. That database didn't happen by accident. ShoeSize is in there because someone went to the trouble of putting it there. Just because your client didn't mention ShoeSize once during your interviews doesn't mean you can ignore it. Even if she says "we never use that", the experienced consultant retains the nagging suspicion that something important is missing ... and won't rest until the mystery of ShoeSize is resolved.

 

We used to say, "show me your data and I'll tell you what your application does." Flippant perhaps, but not altogether wrong.

 

I almost forgot this maxim because it seemed so obvious. Yet I can't remember it being mentioned in a single DDD book or article. I think you're missing an important design opportunity when you neglect to start from the existing data schema.

 

Conclusion: DDD is for Data-Firsters too

 

DDD is first and foremost about studiously matching the domain model to its business purpose. That's hard work. Data-Firsters cannot escape that work - even if running the ORM on auto-pilot seems at first to deliver good results. The schema is only one of the inputs to the ORM; our judgement - what tables and columns to model, how to expose columns or relationships as properties, what data should appear as Value Objects, etc. - is the more important input.

 

Of course domain model objects have behavior. Data-firsters are not satisfied with property-bag classes. They add behavior as they go ... just as Object-firsters do.

 

DDD describes structures and design patterns that favor an evolutionary domain model that serves the business. We sometime data-firsters build those same structures and follow those same patterns.

 

Unit testing is critical to the iterative process promoted by DDD. Our persistence infrastructures must facilitate unit testing. In particular, we must be able to test the model without connecting to a database. Some persistence infrastructures just missed this boat. Big mistake. Unfortunately, many of these infrastructures - I'm thinking of Entity Framework in particular - are associated with tools favored by data-firsters.

 

I'm going to claim that this is a spurious correlation. There is nothing about the data-first approach that requires an infrastructure that makes testing hard. A persistence aware infrastructure does not have to make unit testing hard. That many do is a correctable error. 

 

DDD emphasizes the importance of reducing friction in facilitating continual redesign and re-implementation. Friction discourages us from seeing and making the changes that improve the model. Our code-generating ORM tools undoubtedly introduce some friction into the process. The need to regenerate the domain model simply to change a persisted property's name or accessibility is among the more glaring examples of friction.

 

But I think it's also time for the object-firsters to come clean about the friction they introduce. The friction is not always in the domain model; it pops up elsewhere in the system because of what is not in the domain model classes. Jimmy's book is pretty fair in its recital of the ugliness in the "infrastructure ignorant" discipline. The "no properties" school introduces another, huge source of friction to the process - whatever the compensating benefits.

 

But I digress. The point I want to make is that, if data-firsters tame their unbridled exhuberance for their tools and use them wisely, they too can practice DDD.

 

Then we can all build CRUD apps ... of any sophistication.

Comments (33)

Colin Jack said

at 12:38 am on Jul 15, 2008

@Ward
"When confronted with a brown-field application development scenario I often find myself in the camp that finds value in leveraging an existing database schema during the development of my domain mode"

My feeling is that DDD is not just about the patterns but also the process. A key aspect of this is the extensive work you do with a domain expert (if you can get one) to ensure you build a suitable model. That just isn't going to happen if you practice database first style development, nor will it happen if you start from the GUI and work down.

DDD can obviously be applied on CRUD apps (including brownfield ones) to produce a model and of course, but I think that when you work in such an environment its important to try and stop the DB/GUI totally wrecking the design of the domain model.

Ward Bell said

at 10:53 am on Jul 15, 2008

@Colin
>"DDD is not just about the patterns but also the process". Right on. That's what I thought I was saying.

>"A key aspect of this is the extensive work you do with a domain expert (if you can get one) to ensure you build a suitable model." Absolutely! And if you cannot get one, you are in very big trouble. Using the existing database schema as your only source is to play archeologist to a lost civilization. The burried remains may be all you have to reconstruct that civilization ... but your confidence in your reconstruction will be low (however entertaining).

>"That just isn't going to happen if you practice database first style development"

This one I just don't understand. Why is it not going to happen? What about our use of "data first" technologies for *one moment of* development precludes our use of DDD for *design* and "other moments* of development?

Why will my use of "data-first" technology make a fool of me? I may be a fool in which case no technology can save me.

The major point of this essay is that "data-firsters" are also "Design-first-and-always" people. Or at least they can easily be; emphasis on *easily* by which I mean that "data-first" technologies do not interfere with design or development.

The only intrinsic difference between "data-first" and "object-first" concerns one of the techniques - just one - employed in implementation. As I see it, "data-firsters" are always looking at the database and strive ever to keep the domain model and the schema well mapped. "Object-firsters" are always looking at the demands on the domain model, preferably to the exclusion of storage details, and they reconcile themselves to the constraints imposed by
Both of camps can and should be driven to continually re-work the domain model in light of a relentless investigation of the business purpose. [to be continued]

Alex Simkin said

at 11:09 am on Jul 15, 2008

Collin & Ward:

Why do you need to continue this ages old "holy war" ? It cannot be won.

Let say I am building a 3d modeling and rendering application that will be used in production of the next generation of Hollywood movies. I am concerned with photo-realistic rendering and physics and atmospheric effects. I am not concerned with how I am going to store my data, I can just dump memory in a file and reload it tomorrow.

Now, let say I am building a program that will be used to store some membership information for non for profit organization. There is nothing to compute, just need an extremely high performance structured store for ad hoc reporting and people that will be using this store are non computer savy volonteers. I won'r go with domain model first, even though I will build one afterwards.

Ward Bell said

at 11:12 am on Jul 15, 2008

@colin [continued]

Sorry a phrase got chopped in splitting my comment above. Should read "... they reconcile themselves to the constraints imposed by the database schema as necessary."

>"its important to try and stop the DB/GUI totally wrecking the design of the domain model"
Absolutely agree! Who would want anything to wreck the model. On the other hand, (1) DB and GUI are evidence relevant to the design of the model and (2) the db - if pre-esisting - is a necessary condition of the model design. It is unwise to design a domain model as if the DB and GUI requirements did not exist.

We are agreed that neither DB nor GUI should *dictate* design. The fear that they will drive design de facto is what drives our fear that people will use data-first (and drag-and-drop technologies). I buy that.

On the other hand, for reasons that escape me, there is a widely shared belief that EF and it's ilk makes smart people stupid. I sure hope there is no such corrollary prejudice: that DDD makes stupid people smart.

I think the burden of proof is on the anti-Code-Gen camp to show that code-gen from schema, by its very nature, significantly hinders DDD and supple domain model implementations.

There are arguments to be made here. The temptations of automated code spew; the imposition of re-generation cycles (e.g., for property name changes); obstacles to testing; more I am sure. We can schedule some of them for correction. Some are matters of guidance. Some (re-gen) are intrinsic and therefore the "natural" friction of the technology. Before we despair and leap to alternatives (e.g., poco), we should subject them to the same scrutiny.

p.s.: thanks, Colin, for your measured reply.

Ward Bell said

at 11:45 am on Jul 15, 2008

@alex. Which holy war are we fighting? I would prefer not to fight any war let alone a futile war.

I'm contesting three propositions heard frequently, in one form or another, in this wiki:

- "DDD is for apps of lofty ambition that EF v.1 developers cannot touch without disaster"
- "EF v.1 is too complicated for the only apps for which it is suited: mere CRUD apps (whatever the heck they are)"
- "DDD and EF v.1 are incompatible."

There may be no way to "win" the arguments but at least we can identify the propositions.

My apology if this all seems old hat.


Jarod Ferguson said

at 11:53 am on Jul 15, 2008

I agree that DDD 'Principles' can be applied to a CRUD app using a data-first approach; we currently do this now with EF and have mixed success. There is a lot of value in being able to generate a domain model of an existing schema to get up and running quickly, especially if you are talking about a fairly common crud domain where the db design has been proven time and time again (order management?). Also, there are times when large modifications, such as adding a new module are made to a database, and again, code gen from the db can save time. It seems it gets you 80%.

However for me, the last 20% is the most painful. The feedback cycle when working with the database can be expensive when flushing out the exact specification of the domain model during behavior driven testing. This gets magnified when working with large team’s across multiple environments, dealing with change scripts, db source control, test data etc. Refactoring becomes very expensive and hard on the team... "Whoops, adding those 3 columns and changing that db relation from table x to table y was a bad idea” Working with objects first in this scenario is so much easier to find the 'true acceptance criteria'.

(too many characters… continued)

Jarod Ferguson said

at 11:53 am on Jul 15, 2008

In a perfect world I want to be both a data-firster and an object-firster, depending on the situation. I think EF can work here, where I can use the code gen to update the Schema portion of the model, and then map to already existing c-space properties which I have tested prior to generation. You can currently do this with EF the first time through, but once you start mapping to the s-side involving existing associations, the super quantum theory AI validator kicks in and starts trying to overprotect you from making mistakes and breaking the mapping. I think turning this validation off and allowing EF to fail gracefully on bad mapping would go along way, without necessarily needing a full-blown POCO implementation to make an object-firster happy.

For me its not the persistence noise in my model classes that irritates me, its the style of development that gets enforced by mandating the schema must be updated first, every time, before I can even work with or extend the behavior of my model.

JulieLerman said

at 12:58 pm on Jul 15, 2008

Jarod - while I would love this (relaxing some of the rules) I think the rules are buried further in where the relationship manager does its job in the context. "super quantum theory AI validator" - ROFL

Colin Jack said

at 2:30 pm on Jul 15, 2008

First off sorry my reply was only to part of what you said, your post was quite long so I decided to reply in stages. However when I read further I realized you'd already dealt with some of my comments in the original article.


"This one I just don't understand. Why is it not going to happen? What about our use of "data first" technologies for *one moment of* development precludes our use of DDD for *design* and "other moments* of development?"

So my view is if you start out with the database-first mindset then you've immediately diverged from the vision of DDD. However after generating your model from the DB you might start a long and painful process of trying to work out what the model should look like and redesigning it and the database.

If that's what you do then superb and in fact I've worked on a project where we started with an old model that was designed data-first and refactored it to be more in keeping with DDD. However I think most people working data-first will just rip off the patterns (repository in particular), half-implement them and call it a DDD domain model. It's clear that you are not someone who would go down that path, but from the look of it many do.



"As I see it, "data-firsters" are always looking at the database and strive ever to keep the domain model and the schema well mapped. "Object-firsters" are always looking at the demands on the domain model, preferably to the exclusion of storage details, and they reconcile themselves to the constraints imposed by
Both of camps can and should be driven to continually re-work the domain model in light of a relentless investigation of the business purpose. [to be continued]"

To me that difference is huge though and from my experience the models and related artifacts that the two groups produce are very different. I could go into this more but I think you know the differences yourself, but I definitely don't think they should be underestimated.

Colin Jack said

at 2:31 pm on Jul 15, 2008

@Ward

"On the other hand, for reasons that escape me, there is a widely shared belief that EF and it's ilk makes smart people stupid. I sure hope there is no such corrollary prejudice: that DDD makes stupid people smart."

Perhaps thats just the result of the discussion on this group not being particularly constructiv in general, but it does seem to be getting better.



"I think the burden of proof is on the anti-Code-Gen camp to show that code-gen from schema, by its very nature, significantly hinders DDD and supple domain model implementations."

I don't just think it hinders DDD, I actually think it's a completely different approach. Perhaps I'm wrong though, but if so I'd say you're more likely to get valuable input on the DDD newsgroup:

http://tech.groups.yahoo.com/group/domaindrivendesign/

Colin Jack said

at 2:31 pm on Jul 15, 2008

@Alex
I don't believe this is an age old holy war, in fact I've seen very few discussions on whether DDD can work for CRUD applications. If you do think it's a discussion you've seen a million times then you don't need to read it.

Alex Simkin said

at 6:10 pm on Jul 15, 2008

@Colin

This Was Uncalled For.

Colin Jack said

at 1:53 am on Jul 16, 2008

@Alex
Fair enough, but I do think the law of 2 feet works quite well in these discussions. Re-reading your comments though I agree with you, but I still think Ward has made some interesting points related to topics that have been discussed elsewhere on this Wiki.

Troy DeMonbreun said

at 8:19 am on Jul 16, 2008

I think what Colin was trying to say was (as the old philosophical saying goes) "Take what works and leave the rest". I doubt he meant it in an acerbic manner, much like "The Law of 2 Feet" (which has nothing to do with halitosis, though maybe just as applicable).

Colin Jack said

at 12:34 pm on Jul 16, 2008

Definitely, should never have made the comment at all. Apologies if it came out badly.

Greg said

at 1:36 pm on Jul 16, 2008

@Ward: You reference Jimmy's work in here a lot. I think a better reference might be Eric's work. Based on my interpretation of Eric's work, previous conversations with him, and my own personal opinion would be that there are much simpler ways to do things. Jimmy's work was great but I found it to be more of a "how do I put these patterns together" as opposed to a true look at DDD. DDD is about alot more than just the patterns (hence why they make up <> 20% of the book as a whole) ... DDD is hard and frankly its a waste of time for CRUD type behaviors lacking in behavioral complexity.

Ward Bell said

at 6:05 pm on Jul 16, 2008

book. As wonderful as that book is, it does not contain an example of an application built according to DDD. This is not a defect of the book I hasten to add.

I'd be grateful if you (or Eric) can refer me to other representations of "DDD in Action" that are rich enough and detailed enough to serve as benchmarks.

I recognize that DDD is much more than a collection of interacting patterns. As I recall, it is predominantly about the process of examining and interpreting a business problem - repeatedly, relentlessly - and refining the code to match. Lots of great stuff on ubiquituous language, finding boundaries, and coping with change.. It is not a cookbook; it is, in some sense, an anti-cookbook.

This wiki page does not try to explain DDD. It explores two specific and empirical questions related to DDD:
(1) "Does the practice of DDD in the recommended, object-first way, lead to radically different outcomes than a DDD-meets-EF approach?" and
(2) "What is the evidence that seemingly opposed design paths diverge with respect to the kinds of applications they should tackle?"

The application in Jimmy's book is the only thing I know that even approximates an empirical study of a DDD app. Of course it is just one data point and that data point is not even a real application. But it is a stake in the ground. (part 1 of 3)

Ward Bell said

at 6:05 pm on Jul 16, 2008

AARGH ... Scratch previous comment and let me start again!

Ward Bell said

at 6:06 pm on Jul 16, 2008

@greg - (Part 1 of 3)

I would love to have referred to Eric's work. Sadly, all that I know of his work is in his great book. As wonderful as that book is, it does not contain an example of an application built according to DDD. This is not a defect of the book I hasten to add.

I'd be grateful if you (or Eric) can refer me to other representations of "DDD in Action" that are rich enough and detailed enough to serve as benchmarks.

I recognize that DDD is much more than a collection of interacting patterns. As I recall, it is predominantly about the process of examining and interpreting a business problem - repeatedly, relentlessly - and refining the code to match. Lots of great stuff on ubiquituous language, finding boundaries, and coping with change.. It is not a cookbook; it is, in some sense, an anti-cookbook.

This wiki page does not try to explain DDD. It explores two specific and empirical questions related to DDD:
(1) "Does the practice of DDD in the recommended, object-first way, lead to radically different outcomes than a DDD-meets-EF approach?" and
(2) "What is the evidence that seemingly opposed design paths diverge with respect to the kinds of applications they should tackle?"

The application in Jimmy's book is the only thing I know that even approximates an empirical study of a DDD app. Of course it is just one data point and that data point is not even a real application. But it is a stake in the ground.

Ward Bell said

at 6:07 pm on Jul 16, 2008

@greg - (Part 2 of 3)

I agree that Jimmy's book is mostly about "how [to] put these patterns together." Ubiquitous language - so central to DDD - hardly appears. There is little if anything about the critical search for core domain and management of context boundaries. I'm not denigrating the book in this respect - Jimmy's attention was on implementation practices and no book can be everywhere.

On the other hand, the reader is lead to believe that the practice of DDD is behind his every development step, motivating every turn. I have not read anyone who raised any misgivings on this score - and I've read all 13 Amazon reviews and the 20+ voices of praise in the front pages of the book.If it doesn't exemplify DDD, what is it doing and why hasn't someone said so?

Most important, this wiki (as I write) has been almost entirely devoted to the patterns and practices described in Jimmy's book. We have said virtually nothing about whatever in DDD, in your words, " is more than just the patterns".

Indeed, the most prominent theme in this wiki is that the patterns and implementation technologies (e.g., POCO, the use of a Data-first EF v.1) determine the design and practical success of our applications.

It is as if DDD itself can only be practiced with certain implementation tools and tactics. Why else would so many denunciations of getters and setters, code generation,reporting off the OLAP database, and EF.v.1 repeatedly touch the talisman of DDD

Accordingly, I thought it appropriate to concentrate attention on something that is concrete and focused on the points we are actually discussing. In this regard, Jimmy's book has more to say than Eric's.

Ward Bell said

at 6:07 pm on Jul 16, 2008

@greg (Part 3 of 3)

I don't understand the comment "DDD is [...] a waste of time for CRUD type behaviors lacking in behavioral complexity"

- Is it a waste of time for CRUD apps period or only those that lack behavioral complexity?
- Does Jimmy's application lack sufficient behavioral complexity to warrant a DDD approach?
- How do we know when an app is ripe for DDD?

This last question deserves its own page.

Ward Bell said

at 6:26 pm on Jul 16, 2008

@ Jarod "For me its not the persistence noise in my model classes that irritates me, its the style of development that gets enforced by mandating the schema must be updated first, every time, before I can even work with or extend the behavior of my model."

I agree that this is an important weakness made worse by the fact that one cannot easily test the model without a database connection in raw EF. Mitigations are urgent (We mitigate both problems as you know but this wiki is not about us).

IMHO, the flaw lies in the EF implementation, not in the approach it strives to support.

I take it that your database schema is in constant flux? I don't mean just adding columns either. You'll crush almost any development if you jack the schema often and severely without any team communication. I'm not sure why it would be better to learn about this kind of breakage later (during integration testing) than earlier.

Ward Bell said

at 6:45 pm on Jul 16, 2008

@ Colin "So my view is if you start out with the database-first mindset then you've immediately diverged from the vision of DDD." Absolutely true. And so is what you have to say immediately thereafter.

Moreover, as I point out, data-first tools foster an illusory sense of satisfaction with the first output of a mindless model generation. I am guilty as charged everytime I do a demo of our tool and say "just point it at the tables you want, click generate, and you are done." I have demo'd this way for years. I should be able to make my ease-of-use case AND at the same time emphasize that no one should actually build a model this way.

I've actually thought that the access modifier of generated properties should be "private" by default, obliging the developer to choose which properties to expose and how.

But before I flagellate myself too severely, I must observe the similarly caviler attitude in every object-first demo I've ever seen. "Let's start with Person. We'll give him a firstname property, and a lastname property, and a birthdate property and ... look at the way resharper helps me write these so fast ... I love that tool ...".

Troy DeMonbreun said

at 2:22 pm on Jul 17, 2008

Oh, "flagellate", not "flatulate". Carry on.

Ward Bell said

at 2:26 pm on Jul 17, 2008

@ Troy - Touché, not tushee. Carried too far.

Colin Jack said

at 3:10 pm on Jul 17, 2008

@Ward
Your comments deserve a more detailed comment than this but I thought I'd start by asking if in reality we aren't all closer together than it appears?

When people talk about CRUD applications not suiting DDD then I think they're talking about some aspects of DDD, in particular the costly analysis/design that goes into creating a good model. Are we not better either generating from the database or using a simpler approach to the design, maybe just using active record and a much closer link between the domain and the DB?Even if we do go for a simpler approach I think we can still draw on some of the DDD patterns (repository etc.).

I do however have some issues with the idea of always going for a simpler approach for CRUD apps because as you say they do have complexity and behavior, at the very least state change and validation but potentially a lot more. I thus think that it is worth getting your terminology correct (UL) and trying to create a flexible model as far as possible. For me the key thing is that in such as system the GUI/DB are going to effect the model so there is only so much you can do.

On the book issue, I certainly think agree with Greg and find Eric's book the most compelling resource on DDD.

However I definitely agree with you in that we end up discussing the patterns at the expense of other aspects of DDD. I think part of the problem is that they are easier to explain/use than the other aspects of DDD and they've now caught on to such a degree that they've almost hidden the other aspects of DDD. Although that is a shame but something I don't know what you can do about it and it doesn't seem peculiar to DDD.

Colin Jack said

at 3:10 pm on Jul 17, 2008

@Ward
Your comments deserve a more detailed comment than this but I thought I'd start by asking if in reality we aren't all closer together than it appears?

When people talk about CRUD applications not suiting DDD then I think they're talking about some aspects of DDD, in particular the costly analysis/design that goes into creating a good model. Are we not better either generating from the database or using a simpler approach to the design, maybe just using active record and a much closer link between the domain and the DB?Even if we do go for a simpler approach I think we can still draw on some of the DDD patterns (repository etc.).

I do however have some issues with the idea of always going for a simpler approach for CRUD apps because as you say they do have complexity and behavior, at the very least state change and validation but potentially a lot more. I thus think that it is worth getting your terminology correct (UL) and trying to create a flexible model as far as possible. For me the key thing is that in such as system the GUI/DB are going to effect the model so there is only so much you can do.

On the book issue, I certainly think agree with Greg and find Eric's book the most compelling resource on DDD.

However I definitely agree with you in that we end up discussing the patterns at the expense of other aspects of DDD. I think part of the problem is that they are easier to explain/use than the other aspects of DDD and they've now caught on to such a degree that they've almost hidden the other aspects of DDD. Although that is a shame but something I don't know what you can do about it and it doesn't seem peculiar to DDD.

Colin Jack said

at 3:10 pm on Jul 17, 2008

@Ward
"It is as if DDD itself can only be practiced with certain implementation tools and tactics. Why else would so many denunciations of getters and setters, code generation,reporting off the OLAP database, and EF.v.1 repeatedly touch the talisman of DDD"

I think its just that code gen/reporting off OLTP/non-PI/getters and setters (for GUI) all take away some of the flexibility you have, they erode your control and flexibility with regards to the model or erode its attractiveness. Having said that I personally wouldn't argue that you can't do DDD with getters/setters or reporting off your main DB, in fact I actually use getters/setters quite a lot.


"But before I flagellate myself too severely, I must observe the similarly caviler attitude in every object-first demo I've ever seen. "Let's start with Person. We'll give him a firstname property, and a lastname property, and a birthdate property and ... look at the way resharper helps me write these so fast ... I love that tool ...".

Definitely agreed. Actually reading your comments made me think, if you could code-gen with more flexibility then it could work nicely especially if it let you explcitly define things like aggregates and value objects. Its not going to work for more complex scenarios but as an entry point it could work nicely as an alternative to just going straight for one-one mappings from DB to domain.

Ward Bell said

at 12:43 am on Jul 18, 2008

@jarod ""Whoops, adding those 3 columns and changing that db relation from table x to table y was a bad idea” Working with objects first in this scenario is so much easier to find the 'true acceptance criteria'."

Why not take the challenge posed in this wiki on page http://entities.pbwiki.com/Refactoring-The-Model. Take this sentence as your starting point and sketch out a scenario or two that you believe reveals the problem. Were the columns added - the implied relation moved - in the database first? Or were you contemplating changes in the model first (in which case, why are the changes expressed in database terms?)? My suspicion is that this is actually more easily explored the EF way than you suggest..

Jarod Ferguson said

at 12:40 am on Jul 20, 2008

@Ward
“I agree that this is an important weakness made worse by the fact that one cannot easily test the model without a database connection in raw EF. “
We define repository interfaces for the aggregates and implement them with partial classes on the context, then inject them into our application service layer. We then mock the repository for testing thus taking the db (context) out of the loop. It works very well to test the interaction between the application logic of the service layer and the repository, and also the behavior of the entities.
We keep the repository implementations as small and clean as possible, just simple linq statements. We have a generic fixture which wraps a context and performs rollbacks after each test is completed. It’s slow, so we push more and more to mock as much as possible and run the integration tests less often (Only when initially testing queries, & during the CI process).

Jarod Ferguson said

at 12:44 am on Jul 20, 2008

@ Ward
“I take it that your database schema is in constant flux? I don't mean just adding columns either. You'll crush almost any development if you jack the schema often and severely without any team communication. I'm not sure why it would be better to learn about this kind of breakage later (during integration testing) than earlier.”

Well, with iterative development, you’re going to jack with the schema. We have constant communication, daily scrums, an open pairing environment, build notifications. We use the DB tools in Team Suite, so it’s easy to update the schema etc. We usually don’t have issues with the integration testing breaking at the EF/DB level.

I think where it breaks down is during TDD. When modifying EDM entities and their association’s data-first, the feedback cycle is slower. Every time you want to make a change to an entity, you have to change the db schema a regenerate. Think tracer bullets… to me refactoring data-first is like using tracer bullets in a tank. The developer can’t make adjustments fast enough because it takes so long to shoot again. Too much time dialing the knobs, instead of focusing on the target.

For simple property names, it’s trivial. How about a more advanced scenario with an inheritance hierarchy that may have associations at multiple levels? Data-first, the developer has to think about mapping strategies up front, are they going to use TPT, TPC or TPH? If they are so bold to choose TPH, they’ll have to consider things like which table in the hierarchy may have what database relationships, which fields should be common, how they’ll discriminate over multiple levels, whether classes should be abstract. This is all before having the chance to test whether or not this is really going to solve the customers problems, and make sure it’s not too crazy to maintain. As software developers, our first crack at stuff usually sucks. This is why we prefer iterative processes like agile, xp, tdd.

Jarod Ferguson said

at 12:45 am on Jul 20, 2008

[continued]

From my experience, a developer can flush out an inheritance scenario similar to this with poco’s really fast. If they decide to refactor the structure a few times, it can be done in minutes vs. hours (red-green-refactor). It’s not just time the crunch here, it’s the friction of going slow which wears on a developer. (It does me anyway.) It’s like playing a kick ass game, but you have to wait 5 minutes between every level for the game to ‘load’.

When doing a more complex implementation, the object-firster & data-firster will ultimately get to a ‘similar’ place, with a ‘similar’ schema. I believe that. I just also believe the object-firster may get there faster, with less stress.

Greg said

at 8:11 pm on Jul 23, 2008


"On the other hand, the reader is lead to believe that the practice of DDD is behind his every development step, motivating every turn. I have not read anyone who raised any misgivings on this score - and I've read all 13 Amazon reviews and the 20+ voices of praise in the front pages of the book.If it doesn't exemplify DDD, what is it doing and why hasn't someone said so?"

I was one of those 20 voices.

Jimmy went a long way towards bringing many DDD concepts more mainstream and you are right that "how tos" were any area that was sorely missing. There is a ton of stuff that remains uncovered that is covered by Eric (fitting it all in one book doesn't work to well)

That said, I would prefer to see the domain examples from eric as possible as although they don't provide code they do provide more context and explanation

You don't have permission to comment on this page.