Simply stated, software is used to model the real world, or problem domain, in the computer to solve a real world problem.
A key question that needs to be answered initially is, “Where do you start?” More specifically, do you start on the Problem Domain side? On the Solution side? Somewhere in the middle? I've always leaned towards the “Problem Domain” side – seems to me that it’s the right answer in an agile/OO world.
Jon Kern at technicalDebt.com summed up my thinking in a post titled Good Judgment is Agile:
...The key to development is separation of concerns
the core is the problem domain built to support the requirements. get this wrong, nothing else in the app matters. nothing.
- not the UI/UX.
- not the 5th normal form DB.
- not the worlds most articulate UML models.
- not the worlds best cruise-controlled, TDD, 100% test coverage.
- not the best joshua bloch-/steve mcconnel-blessed code.
this core generally transcends UI, database, and even the language chosen to code the app. In other words, the "problem domain" reflects the relatively stable "business" world. I know it sounds trite, but despite all our wonderful software advances from green screen to now, the world of mortgage/insurance/banking has changed little, fundamentally, or relatively.
- the app is all about the "business" needs
- the User Experience/UI is a separate thing
- The persistence is a separate thing
Let’s say that there is a business requirement for doodads and thingamajigs:
A doodad and a thingamajig must be captured while creating a …
I often see a start on the solution side that goes something like this:
Doodads and thingamajigs, hmmm. They have a code and description so they’re just simple reference data. We’ll use a ReferenceDataWidget to supply a list of reference values from the database.
On the problem/solution scale “ReferenceDataWidget”, “list” and “database” fall on the solution side.
Why is this a bad thing? Because there isn’t any representation of the problem domain, i.e doodad, and there isn’t any means for abstraction of the problem, which is necessary to reduce complexity. The client of this solution will be coupled to a specific solution implementation.
Steve McConnell, in his classic book Code Complete, addresses this abstraction and complexity when he talks about Programming in Terms of the Problem Domain:
…Another specific method of dealing with complexity is to work at the highest possible level of abstraction. One way of working at a high level of abstraction is to work in terms of the programming problem rather than the computer-science solution.
So how about something like this:
The client of this solution will be coupled to an abstraction, Doodad, which can then be implemented (or re-implemented) in any fashion. This decouples the problem domain and the solution, which allows the solution to change without affecting the client.