Lately I've been blogging about architecture (including various gripes), including the debate about architecting applications around custom objects (and collections) versus leveraging DataSets. I've been very impressed with CodeSmith and the recent buzz around O/R mappers and Microsoft bailing out on ObjectSpaces has led me to read other people's blogs regarding these topics. One consistent item (other than the techie debates) has been the reference to Martin Fowler's book Patterns of Enterprise Application Architecture. So I bought a copy from Amazon and read it this weekend. Admittedly I have read the infamous GoF Design Patterns book some time ago and came away feeling somewhat enlightened and somewhat indifferent. In short, I feel much better about the enterprise patterns book than I did after reading Design Patterns. Clearly Martin Fowler is a very experienced, and intelligent person who has some really interesting ideas and much to share with the world that is beneficial. Most likely the reason I'm not totally jumping for joy as many folks are after reading this book is not the fault of the author at all, but rather the fact that I make my money developing solutions using Microsoft technologies (.NET specifically). The book seemed to be much more geared towards Java folks, than us .NET folks; however, after reading it, I was pretty easily able to brush off many of the "object bigots" that are firm in their resolve to write every application around a domain model. It also re-affirmed my belief that typed-DataSets are indeed the coolest things since sliced bread in the .NET world. Why? I'll get to that...
Fowler lays out three main architectural designs: Transaction Script, Table Module, and Domain Model. With all of the hype around domain models that I've been reading in various blogs, I was starting to wonder if perhaps I needed a forceful "paradigm shift" to be convinced of switching from my affinity towards the "Table Module pattern" (i.e. my use of typed-DataSets) to a "Domain Model object bigot." With the risk of doing a huge disservice to Fowler's description of the Table Module pattern, the Table Module pattern is essentially Record Set pattern centric (DataSet-centric in the .NET world al a Duwamish Books). The main criticism I've heard about the Table Module enterprise design pattern (which is so dominant in the .NET world) is, "DataSets are not OO...Domain model is OO and is therefore better." After reading Fowler's book, I'm more convinced now than ever that I've been on the right path in using typed-DataSets quite liberally. That is not because I'm trying to imply that "DataSets are better than custom objects (or rich object model...whatever)" but for my endeavors (mostly developing in my ASP.NET applications), DataSets have been “better for me” because they are the right tool for the job IMHO. Again, for the record, I'm not saying that DataSets are always the way to go! Quite the contrary - I think Fowler does a wonderful job of explaining to the reader that every business problem that drives an application's architectural design is unique, and there is no one answer to every problem. He also does a wonderful job of explaining that the patterns in his book are simply a starting point and that you have to adapt them to your needs. That being said, here are a few lines from Fowler's book that I found very interesting considering the buzz around using the Domain Model architecture and use of O/R mappers to support that model in .NET:
Looking at .NET, Visual Studio, and the history of application development in the Microsoft world, the dominant pattern is Table Module. Although object bigots tend to dismiss this as meaning only that Microsofties don't get objects, Table Module does present a valuable compromise between Transaction Script and Domain Model, with an impressive set of tools that take advantage of the ubiquitous data set acting as a Record Set. As a result Table Module has to be the default choice for this platform. Indeed, you can build a Domain Model just as easily in .NET as you can in any other OO environments. However, the tools don't give you the extra help they do for Table Modules, so I would tolerate more complexity before I felt the need to shift to a Domain Model. (P.101-102).
This is reasonable given that fact that data binding is huge in .NET, and the tools are there to support the DataSet [Record Set pattern] in a very big way. Of course you can data bind to custom objects as well and as a disclaimer it will be even easier in Visual Studio .NET 2005. Either way, I think the argument still stands that if you are creating custom business objects and purposely avoiding the use of DataSet objects, you are essentially having to write your own functionality that the DataSet provides for you such as serialization, XML support, sorting, filtering, relationships, concurrency (i.e. diffgrams), etc. If you have the time for that development and the time to test as well, more power to you.
As another compliment to Fowler, his First Law of Distributed Object Design makes complete sense to me: "Don't distribute your objects!" That is, if you can avoid it. This takes me back to when I was contracting at a local utility company. Another contractor (hi Dave), found that he increased performance significantly by eliminating our "application server" between the Web Server and the Database server. That was contrary to our understanding that more CPU and distribution of work is better! Of course, that was naive at best because we should have learned the lesson from COM/DCOM that in-process calls always outperform out-of-process calls, plus you can factor in network latency, etc and it's not difficult to see the problem. This is one of the points Fowler makes very clear, and these kinds of points are made throughout the book which is worth the read alone. Fowler also gives you some very useful patterns for dealing with remote object issues such as Remote Facade and Data Transfer Object (DataSet strength again as a DTO). He explains very thoroughly the concept of course-grained objects versus fine-grained and when to use both as a related topic.
Again, I think I'd be a lot more excited about this book if before starting to read it I had a mapping of terminology. Then again if you reference the patterns enough times, you'll have it figured out eventually. NOTE: as a disclaimer, the the following are my own mapping descriptions that are subjective interpretations, but I'm probably more right than I am wrong. :-)
- Front Controller pattern = .NET HttpModule
- Page Controller pattern = .NET HttpHandler
- Template View pattern = .NET Web control properties as HTML attributes
- Record Set and Table Module patterns = .NET DataSet
- Value Object pattern = C# Struct
- Data Transfer Object = Marshal by Value
The book was very well written and it is interesting to read from the perspective of enterprise architecture outside of the Microsoft world. Some of the patterns that I read about I found myself asking why I care, but that has to do with the Microsoft tools taking care of a lot of that work for me (right or wrong). So in that sense, like the Design Patterns book, I found it a little esoteric but at the same time the patterns (distribution patterns specifically) are a a great reference. Which brings me to another thought: with all of the patterns being referenced throughout almost every page, it can be somewhat like reading a "Choose Your Own Adventure" book. But believe it or not, that is quite convenient. I actually found myself referencing and reading (and re-reading) the patterns so much that it took me about 2 days just to hit page 50. :-)
I did enjoy the book, and I do recommend reading it, and at least I came away feeling as though I've made a geeky connection to my Java buddies who love things like Struts, and the Domain Model OO purists out there. This, despite the fact that I'm going to stick with the Table Module architecture using .NET whenever possible. Ultimately, all things are subject to change as Folwer says in his book, "one certainty of software development is that it never stands still" and as Eric Sink so cluefully pointed out "C = G + LT" in his career calculus blog post. I'm always looking for better ways to solve problems and I think that's something this book definitely brings to the table. Martin Fowler writes early in the book that he doesn't claim to have all of the answers either and he hopes the book is at the very least useful. Mission accomplished Martin. :-)