Thursday, April 17, 2008

WCF: Design of Client Domain Objects

The client Domain Objects [Evans] (aka business entity - BE) must be related to the data contracts provided by the web-services. Still, they will need to be enhanced with e.g. dirty-tracking, validation, state, property conversions (xs:date), business rules, and other aspects needed to produce a fully working client application. This article describes how to achieve this when sharing domain objects across layers is not an option (i.e. interop with JEE services), and the same applies to AOP.

There are two models for this: annotating the BEs with XML serialization attributes to decorate the WSDL data contract, or creating separate Mapper classes [Fowler] in addition to the BE classes. The mapper will then map to and from the service proxy DTO objects [Fowler] at run-time. Note that the mapper model will be required whenever the BE is significantly different from the data contracts. Thus, BEs should be implemented using the first model to the maximum extent possible, only using the second model for advanced mapping requirements.

The decorator option is easier, performs better, and gives less code to maintain - but requires knowledge of XML serialization and will not give compilation errors when the data contract changes (even if the proxy is updated). Good integration test coverage is needed to make this option viable, i.e. to detect that the DTO's XML payload has changed.

Easier, less code: Only one BE class to implement and maintain as the BE is a Decorator object [GoF] wrapping the "DTO" XML. Note that there is no auto-generation of these classes and that there are no mappers or DTO objects. The BE classes are shared directly by the service proxies.
Performs better: There will only be one de-serialization step directly into the BE because it wraps the XML directly. This also applies to any nested child objects and collections - there will be no looping code to create and map the BE structure. The same applies to sending BE objects to the services - they will be directly serialized into "DTO" XML.
Contract change risks: As the BE classes are not auto-generated from the data contracts, changes to the contracts will not be automatically reflected in the serialization attributes on the BE properties. As (de)serialization happens at run-time, any mismatch between the XML and the serialization attributes cannot be detected by the compiler. Thus, adequate integration tests are required to detect that BE properties are not being set/read during (de)serialization. Breaking data contract changes will require that the serialization attributes are updated accordingly.

The mapper option is also quite easy, but performs worse and requires more code to be implemented and maintained (two classes: BE and mapper). However, it requires no knowledge of XML serialization and it will give compilation errors when the proxy + DTO objects are updated after data contract changes. Note that good unit testing is required to ensure that the mappings to and from the DTO objects are correct, including the complete object graph (nested child objects and collections).

Quite easy, more code: Two classes to implement and maintain, one BE class and one related mapper class. The mapper class must cover nested child objects and collections, both to and from the DTO objects. The DTO objects are auto-generated and will never be manually maintained by developers.
Performs worse: In addition to the de-serialization step of the DTO objects, the service agent must execute the mapping code to fill the BE object with data from the DTO object. Add to this extra transformation looping through nested child objects and collections, and the performance gets proportionally worse with the complexity of the object graph.
Contract change risks: The DTO objects are auto-generated based on the WSDL and are thus always in synch with the data contracts. Any breaking changes to the DTO classes will cause the mapper classes to give compilation errors. Breaking data contract changes will require that the mapper classes are updated accordingly - both to and from the DTO classes.

To complement this BE design approach, read the programming models for the Decorator option and the Mapper option to learn about the technical details and issues of each option.

No comments: