In an attempt to quench my thirst for all things C# and having already torn through the great .NET Framework Design Guidelines and less-great Effective C# I grabbed a copy of Applying Domain-Driven Design and Patterns (With Examples in C# and .NET) by Jimmy Nilsson.
The book is obviously based around domain models but also gives some coverage to test-driven development, NHibernate, design patterns, refactoring, code-smells etc.
This is only a first-look as I’m only up to page 130 of the 500+ the tome weighs in at but here are a few observations so far.
The Impedance Mismatch Between Domain Model and Relational Database
One annoyance with the book is that is identifies and discusses problems and then offers no discussion or ideas for a solution before moving onto another topic.
A good example is this section which touches on the mismatch between the primitive types of .NET and SQL without the consideration of how/where to check this, the fact that SQL types can be null with no regard to .NET 2’s INullable, bit flags or ‘magic values’.
How to Recognize If an Application Will Be Long Lasting
Another perfect example of the previous problem. The heading asks the question but the short anecdote about how a hacked together app became mission critical fails to answer it.
Use public fields
Jimmy proposes a number of techniques that fly in the face of .NET Framework Guidelines and other solid material. This is highlighted by the phrase;
As long as the fields are both readable and write-able and no interception is needed … public fields are at least as good as properties.
Perhaps Jimmy doesn’t know that converting a field to a property later will break binary compatibility with anything using your assembly.
Expose internals for testing
…expose sub-results so they are testable
flies in the face of hiding the implementation and Jimmy does at least refer to this balance but the whole idea of exposing unnecessary details for the sake of being able to test them gives me a shudder.
Throwing aside the whole question of whether you should write unit tests that test implementation rather than interface a better solution would be to add a
block to classes that really need to expose their internals to your test tools and compile with that switch set in your testing environment.
Use static factory classes!
Jimmy extracts the factory methods into a new class and but then leaves them static. A static class throws away substitutability, extension and indeed everything that makes OO great for the sake of being able to access it like a global variable.
Expose IList as read-only
On page 102 Jimmy refactors a “public IList Children” field firstly making it a read-only property and then creates a AddChild method which is fine but then how will he stop people modifying his IList? With ArrayList.ReadOnly(children) of course bemoaning how clients still see .Add etc.
Hello Jimmy, let me introduce you to IEnumerable.
Use reflection to set internal properties from Factory & Repository!
Jimmy describes how some properties should be read-only but then the Factory and Repository need to set the values. He proposes reflection.
Maybe Jimmy missed the memento pattern and dislikes the internal keyword.
All the code samples use _ for internal members – something that Microsoft guidelines and their FxCop tools are keen to stamp out. Besides being ugly it also reeks of the obsolete Hungarian naming prefixes.
The whole book is written in “I still remember”, “I worked on an application”, “After that, I tried Domain Models”… It makes for slow reading at times.
Well that about wraps it up so far.