July 2005 - Posts
A system with a complex domain model often benefits from isolating the domain objects from persistence logic. Your domain objects are then Plain Old CLR Object (POJO), or PI-O (Persistence Ignorance-Objects). In my case I want the decision about which infrastructure to choose for persistence support to be made as late as possible, and to be dealt with iteratively. One possible solution is the Repository Pattern [Fowler, PoEAA] which mediates between the domain and data mapping layers using a collection-like interface for assessing domain objects. Also, repositories help you reduce object access by creation and traversal to keep your domain model clean from muddling associations and endless tangles. Another advantage is the decoupling from the client which leaves you with more freedom to change the implementation of the repository. You can take advantage of this to optimize for performance, by varying the query technique or by caching objects in memory. Performance is one of the reasons to rewrite large portions of our DNA n-tier focused web application. From a Domain Driven Design [Evans, DDD] point of view repositories belong to the domain model. Then how do you, since repositories use the persistence infrastructure, maintain the low coupling between the domain model package and persistence package? Lets picture a solution based on the Repository Pattern.
The domain model contains a Customer domain object and a CustomerRepository which defines one operation ForCustomerId and returns the customer with the specified id. The CustomerRepository strategy is to delegate to the persistence infrastructure CustomerMapper to get the job done. As you can see in this very simple example is that there is a bidirectional relationship between the domain and persistence packages. Do I hate cyclic references!
A lot of ideas presented in the next picture can be found in Steve Maine’s post. While I discussed this with Jimmy Nilsson he came up with two (preferred) solutions.
a.) Put the repositories in another assembly, but think of them as conceptually belonging to the Domain Model.
b.) Put the repositories in the Domain Model assembly and use an abstraction layer which the repositories are programmed against.
I don’t like the idea of another abstraction layer since it tends to make the persistence infrastructure even harder to use (efficiently with level of indirection). Putting the repositories in a separate assembly is the Separated Interface Pattern [Fowler, PoEAA]. Separated Interface defines an interface in a separate package from its implementation.
Sidenote: Experienced developers (from the COM/DCOM era) would possibly extract an interface for each domain object and put those in a separate package. The persistence package would only have to know about the interfaces package and instantiate implementations using reflection. And thus skip the whole Repository & Factory solution. I think this is excessive, not only because you (normally) have far more domain objects then repositories, but also because implementation changes in domain objects often require the interface to change as well. The dollar cost of continuous learning/modifying and refactoring rises and shouldn’t discourage developers from executing these best practices.
One awkward thing about separated interfaces is how to instantiate the implementation. I use a separate factory object, RepositoryFactory which returns Repository instances to the client. To bind an implementation to the RepositoryFactory I use the Plugin Pattern. Since the .NET Framework has great support for reflection I dynamically load the assembly containing the repository implementation and use the Activator class to create an instance.
Rock solid, comments?
Jimmy makes an interesting point.
The Ubiquitous Language is also extremely important in the Service context.
A set of services enable several applications to work together through Messaging. The collection of messages is a Context Free Language (DataContract in XSD) where a message together with its operations define a context (ServiceContract in WSDL). BizTalk, for example, is a very expensive Message Translator which translates messages in a certain context (BizTalk knows the context because we tell him) to a Context Free Language. Applications who are aware of this Context Free Language map incoming messages to the format it uses internally (Message Mapper). Underneath this Message Mapper lives, in terms of DDD, the Ubiquitous Language. A Context Free Language is an Ubiquitous Language itself and is often referred to as the Canonical Model. The Ubiquitous Language in the context of a Service is the Canonical Model. RSS is a perfect example of a Ubiquitous Language at Service level, which we use to exchange content through Messaging.
On the winfx.indigo newsgroup the question was asked whether Indigo would be available on the .NET Compact Framework. During the Tech Ed Europe 2005 this question had already been answered with “no current” plans. Yesterday Richard Turner (Product Manager, Web Services Strategy) replied with:
With regards Indigo on the CF, we're going to be looking into how and when we might be able to get Indigo into the CF after we ship Indigo V1. "No plans" means literally that - we don't have a plan, timeline, schedule or commitment on whether or not we can get Indigo into the CF, but it is our intention to do so at some point in the future.
This leaves room for people like Casey Chesnut the author of CFWSE2 to work on CFWSE3 and have feature rich wire-level interoperability ready when Indigo ships.
Sorry, object relational mapping has been discussed in detail over various message boards, architecture groups, newsgroups and whatnot. Every now and then real-life projects are still struggling.
Most of today’s applications are developed with rich object-oriented business/domain models techniques while still using a relational database underneath. The are a lot of tools that bridge the mismatch between these two worlds. The mapping layer between your object model and relational model often called persistency layer often leads to unacceptable slow systems. The high level of abstraction is mainly the reason for certain performance problems. Most of these tools implement the Query Object Pattern. A Query Object is geared to form queries of various kinds and to turn those objects into the appropriate SQL query. The Query Object uses metadata abstracted from the relational schema and metadata (or reflection) which describes the mappings between the relational schema and object-model schema. The output produced by a Query Object is often referred to as a Dynamic Query. Since most Query Object implementations in today’s tools don’t offer the possibility to consume non-functional requirements or have self-learning capabilities, the actual SQL queries aren’t always optimal. The high level of transparency promotes the developer to stop caring about access and navigations paths into the relational database. The result, code that won’t reach the required performance, despite an otherwise good architecture. What makes it even worse are the developers or program manager accusing the object relational mapping tool for delivering poor results. Partly not true! One of the biggest mistakes you can make in this case is to ditch the object relational mapping tool and to take the “write one ourselves” approach. There’s a high probability that you’ll drown in the details of creating such a tool/framework and eventually end up making the same mistakes, or end up with a less flexible and more traditional data access layer.
Sounds familiar? Perhaps you need a tool/framework supporting the DataMapper Pattern to write mappings by hand and to save you from writing tedious code. The only (open-source, stable) .NET tool/framework I know supporting these requirements is iBATIS.
Don Box mentions the First Indigo Book On The Shelves, Programming Indigo by David Pallmann. Programming Indigo is a how-to book so don’t expect an exhaustive Indigo reference. I bought my copy at last week’s Tech Ed.
Roy commented on this post with a link to his Testing Guidelines. Very useful.
A while back I linked Roy's
post on how to view the Tech Ed 2005 Orlando streams the hard way. Alex found a simpler solution
After a full week of Connected Systems I’ve seen the light. It just struck me… I’ve been thinking away what this weblog actually means to me. I consider it to be just another Endpoint to my thoughts Service.
One my thoughts service endpoints, and actually the Endpoint you are now consuming uses RssProfileBinding with a Simplex Messaging Pattern. You can just as easily use one of my other endpoints: my comment Endpoint using HttpProfileBinding (Simplex) binding, or my contact Endpoint using SmtpProfileBinding (Simplex, Request-Reply) binding, or chat Endpoint firstname.lastname@example.org using MsnProfileDualHttpBinding (Simplex, Request-Reply, Duplex) binding, or talk Endpoint using AirProfileCompressionWaveBinding (Simplex, Request-Reply, Duplex) to get in tuch.
and thus I changed the name of my weblog.
All good things must come to an end.
A real eye opener was the Chalk & Talk session by Clemens and Steve. During this session they tried to answer the question “Does SOA really exist?”. Since none of the Service Orientation tenets speak about architecture the abbreviation should be changed to SO/A. Yesterday I noticed that Christian used separate messages namely AddRestaurantRequest, AddRestaurantResponse, RateRestaurantResponse in one of his examples. I heard Clemens earlier this week saying that an operation should have exactly one in-message and optionally one out-message. OK but composing messages inferred from arguments for each operation in your service contract isn’t that much different from using arguments in an envelope. I haven’t heard any speaker about the different types of messages (Command Message or Document Message) nor message format (Canonical Data Model). This led to an exchange of ideas on messages afterwards with Alex and Frans. I introduced them to an industry standard B2MML to integrate business systems such as ERP and supply chain management systems with manufacturing systems such as control systems and manufacturing execution systems.
Anyways, after a good night’s sleep I conclude:
It is still a long way to message oriented systems (services). Indigo indeed rocks hard to build, with the knowledge we have today, connected systems based on message oriented principles. We have the tools today to build working systems on the current ASMX & WSE-* stack but these systems aren’t necessarily message oriented. The SO/A spokesmen still have a couple of gaps to fill. A professional developer should attend to Tech Ed (-like) events at least once a year.
“properly” Connected Systems are the future!
This is a great environment to exchange ideas and to meet and talk to interesting people. To all the people I have met, thanks for contributing to a great atmosphere and highly motivating discussions!
Christain posted the files for this session and forwards to Yasser Shohoud’s website for the IndiTunes sample.
More Posts Next page »