Does SOA require Object-Message mappers? It depends.

Steve Eichert blogs about the question if we need an Object-Message mapper (O/M mapper he calls them) in a Service Oriented Architecture (SOA) world. It's my understanding that he thinks we need an O/M mapper when we're going to use SOA. I beg to differ.

A couple of months ago, in the microsoft.public.objectspaces newsgroup a lengthy discussion was held about the topic 'Is an O/R mapper useful in a SOA world?'. The reason for this discussion was of course: how will O/R mappers be affected once SOA is widely accepted as a solid architecture for building software systems. It turned out that the Domain Model-followers (let me call these 'Fowler followers') said that SOA would affect O/R mapper usage and the people who see advantages in the Manager Model (separate classes which solely process data passed in, like an 'OrderManager'. Often mimicing business processes on a rough 1:1 basis) didn't see that happen.

When you use the Domain Model, you (generally speaking) define business logic in your entity classes through inheritance and/or aggregation. This means that you add for example business logic related to customer entities to the customer entity itself. The average result of this is that the vast majority of your application's business logic layer's API is formed by the set of Domain Model classes ('Domains') you've defined. A problem arises when you want to make this API a service which has to be used by other tiers in your application, for example a set of GUI tiers on desktops and webservers. Communication between these tiers and the 'service' requires that you can map messages used to communicate between client and service (or service and service) onto the entity objects defined. In a sense, this can require a tool to make this an easy task: an O/M mapper.

When you use the Manager Model, you don't have to. The reason for that is simple: a 'Manager' in the Manager Model acts as a service by itself, it's the task of the Manager in a Manager model to provide a service. This means that you use the service in a more procedural way, like you are doing today with a webservice. Data passed between client and service (in this case the Manager or for example a 'Manager manager' or 'Manager dispatcher') or service and service can contain entity objects, but also data which will be transformed into entities inside Managers. Does this require an O/M mapper per se? No, not at all. A tool to connect method call to method definition is more appropriate, thus a tool which will be used to design the SOA architecture.

It thus depends on how you design your software in general: do you want to use your entity objects 'by value' (and thus do you want to apply logic on them by passing them to a service object like a Manager) or do you want to use a rich Domain Model where the entities are used 'by reference' because they form the service?

Thinking about this, I come to the conclusion that the question is not: do we need O/M mappers in the SOA world, but: do we need the Domain Model in the SOA world? With the advantages of easy projection of functional descriptions of business processes on Manager Model classes in the hand, with the absence of the necessity of yet another tool to map data to objects (because in the Manager Model, the SOA architecture tool will be sufficient), I can only say: for me, we don't need the Domain Model in the SOA world. We can do just fine using the Manager Model approach, which doesn't suffer from the disadvantages the Domain Model brings to the table in a SOA approach. This doesn't mean the Domain Model doesn't have a place in the software world, it's my conclusion that the Domain Model (and thus O/M mappers) do not fit SOA and if you want to use a SOA-oriented approach, it's thus best to use the Manager Model instead of the Domain Model

15 Comments

  • I agree.



  • Interesting thoughts and well presented.

  • Frans, Frans, Frans. I have to admit I didn't expect that this would be your conclusion.

    :-)



    To me (if I skip the ordinary "it depends")it's not one or the other most often, it's a combination. I mean manager model and domain model. Unfortunately I'm so swamped with work that I don't have time to blog right now. I'll get back as soon as I can.

    :-)



    Best Regards,

    Jimmy

    www.jnsk.se/weblog/

    ###

  • Jimmy :) Sorry to dissapoint you ;)



    I find it a bit weird to combine domain model and manager model, as domain model (as I understand it) requires that BL logic is placed inside 'domain objects' which thus means that the BL logic is not placed inside manager objects. I don't see how these can co-op very well...

  • Well, you didn't disappoint me, just surprise me.

    :-)



    I like what Eric Evans writes about this in his book called Domain-Driven Design. He talks about services (both within the Domain Layer and the Application Layer) and the entities and value objects. I know what you think about the term "entities".

    ;-)



    As I understand Eric, different kinds of behavior fits best at different places. Manager-like behavior shouldn't be "forced" into the entities.



    Heck, this is a huge (and interesting) topic and we could go on forever. What I mostly reacted on was that you sounded as if using a Domain Model wasn't needed or even a good idea with SOA. If it's a complex domain and you want the abstraction, I think a Domain Model is a good choice here. And a tool like your LLBLGen helps a lot to achieve productivity of course!

    ;-)



    Best Regards,

    Jimmy

    www.jnsk.se/weblog/

    ###

  • It might surprise you, but I don't think a domain model is a good idea in almost any situation. :)



    It's not a technical issue, it's a more abstract issue: I've learned during the years that one thing is THE most important thing of a piece of software and that's maintainability. What I've learned about maintainability is that it's KEY for maintainability to have a very strong connection between functional design and your 'functionality described in a programming language' as I like to describe it: your sourcecode.



    The more easier it is to project a functional design onto sourcecode, the stronger the connection is (and vice versa!). A domain model in most cases will not be able to give you that strong connection because it is a result of a translation (Evans has written about that problem too). Most complex systems still try to describe procedural processes, try to automate what's procedural. It's best to solve these problems with a system which therefore stays close to the procedural process description it has to describe. A domain model with process logic scattered all over the place is therefore not a wise solution. At least that's my opinion :)

  • I follow your reasoning and I see merits in it. But, I belong to the Fowler followers still.

    :-)



    The reason I got surprised was that you don't think Domain Model is useful. Combine that with that you have built one of the best OR Mappers for .NET and that you recently said that you was going to write positive things about OR Mapping as often as you could.

    :-)



    Best Regards,

    Jimmy

    www.jnsk.se/weblog/

    ###

  • Heh :) I see your confusion. Let me elaborate on this :)



    I see O/R mapping as something different than the application of the Domain Model. The reason for that is that I refer to the 'entity' concept as the corner stone of the data-centric core of my application. Not Fowler's Entity, but Chen's Entity. To apply O/R mapping techniques, you can work with entities in an OO environment with ease: the data with little behaviour.



    By using entity objects, it's easier for manager style BL classes to work with data, because they can do that in a typed way: by directly refering to an entity object instead of a row in a datatable. Because this has sometimes limitations (work with a list of orders with customer names for example: you need a join and a subset of the fields resulting from that join) I added 'typed lists', which are 'views' defined on entities.



    I thus see it more separated: entity related logic which is bigger than very simple field-validators or simple entity validators (is order date <= shipping date?) should be placed outside the entity object itself as it most of the time spans more than 1 entity (and is thus not rightfully placable in an entity). However, by doing so doesn't mean O/R mapping is not useful, on the contrary :) The logic is simply placed outside of the entity object, grouped together in manager classes which mimic procedural (sub)processes and which consume the entity objects. Consuming entities wouldn't have been possible without O/R mapping :)



    I find it sad that O/R mapping is connected very tightly to the 'domain model' by some people as it is a technique which stands on its own. By tying it to 'domain model' as a part of the domain model, people who do not grasp the domain model or don't want to use it, will probably also assume O/R mapping is not for them, while that conclusion is not a correct one :)



    Therefore I hope that more and more people will simply discuss the technique of O/R mapping NOT related to 'domains' but solely as a technique to transfer relational model into an object model or vice versa and that it can benefit your own logic. HOW you then implement your own logic (domain model or manager model or even different) is up to you :)

  • Ah, thanks for clearing that up for me! Now I understand you (again).

    :-)



    Honestly, I think this is the first time I've heard about OR Mapping in another context than when the Domain Model is used. Not that they *must* be connected of course, I just hope it explains why I didn't understand you at first. Interesting...!



    Best Regards,

    Jimmy

    www.jnsk.se/weblog/

    ###

  • Hi Frans,



    The Domain Model has it's strength in attaching behaviour to the data and taking advantage of OO goodies like polymorphism and the "push" model. The "Manager Model" has severe limitations in this aspect and tends to encourage parallel method overloading in the Manager classes and inheritance in the data entities + interrogation of the properties of the data entity classes all the time. In fact you can look it this way - the domain classes "happen to have" some (not all) of their data(attributes) persisted in the database, but that's not the most important thing.



    Best regards,

    Deyan

  • Hi Deyan and Frans,



    For what it's worth, I think I've seen something like five very different ways of dealing with the Domain Model during the last few months. Half a year ago, I thought I understood how it was used "all the time"...

    :-)



    Best Regards,

    Jimmy

    www.jnsk.se/weblog/

    ###

  • Hi Frans!



    About combining the Manager approach with the Domain Model approach:



    Say that you have a EmployeeManager.RaiseSalary(employee emp, double percent) method.



    Now, either you can put the actual business logic in this method, or you can create another method on the employee object, called Employee.RaiseSalary(double percent) and just forward the call to that method of the passed along employee object. Or - you can mix.



    In the extreme case, when all the BL is in the employee object, your Manager method would become empty and arguably redundant, Like this:



    EmployeeManager {

    public void RaiseSalary(employee emp, double percent) {

    emp.RaiseSalary(percent)

    }}



    In this case, why would you bother calling EmployeeManager.RaiseSalary()? Why not call employee.RaiseSalary directly instead?



    But what if the story went like this? You started out by creating the EmployeeManager.RaiseSalary method, putting all the BL in it. It worked swell. Clients started calling the method and life was a dream. Then one day, becuase you are such a neatness freak, you decided to refactor in such a way that you created an employee.RaiseSalary method, moved the BL to that method and modified your Manager method into the straight delegation in the example above.



    Everything works as before, clients can still call your service, sweet.



    Following this logic you might wind up with a Manager layer that is little more than a facade. But on the other hand, you could add aspects to the Manager methods that wouldn't necessarily fit on the domainb objetcs themselves: For instance, every time a Customer is deleted by a low-level employee, an Email should be sent to the Big Boss so he can verify the action. I don't want to put that email sending logic into the Emlpoyee.Delete method, because it should only be sent under a very specific use-case, but not when a customer is deleted during other use cases.



    So, IMO, a good way of combining the Manager and Domain Object models is by implementing service-like methods in the Manager/Service layer that correspond to use-cases, and then to take out common functionality from different use-cases and put it in the domain objects to be called from the use-cases/services in the Manager/Service layer.



    On the third hand: Of couse you don't /have/ to put the factored-out common BL on the domain objects. You might as well put that as well into Manager/Service classes. But the point is, you are /free/ to put this code on the domain objects without breaking the beneficial Manager/Service model.



    So, what's the arguments for where to put the freely disposable factored-out and reusable between use-cases code?



    Well, in short I find these arguments to carry weight: Some people find it immensly clarifying to distribute a lot of the BL code over the Domain Model, and I suppose that if you find the application much easier to code this way, then go for it. Others (I am often one of them) think that there is a great benefit in keeping the BL separated out into a layer of its own (the Manager/Service layer) where it can be easily found and where it can be modified and recompiled without having to recompile the Domain Model (or whatever you want to call a "Domain Model" stripped of BL methods)



    /Mats





  • Good post, Mats! :)



    Not as a surprise, I agree with the far most of it :)

  • I agree with you. The Managed Model is more maintainable in the long run. But people have been so much into OOP, they always want to keep data and functionality together. That´s why they had a difficulty with MTS in the first place. And that´s why they want persistent objects with methods like Save() on them.



    I, however, would vote for more differentiation between service (manager) and data. "Real" objects have their place (e.g. maybe to represent a drawing in memory). But when it comes to transporting data, functionality should be separated from data.



    An people will realize it, when they start to develop UDTs for Yukon. Once you start using a UDT as a column type, you can´t replace it´s assembly in Yukon anymore. Understandable - but very inconvenient.



    So what do you need to do? Pack your data in one UDT class definition and assembly and base you columns on that "anemic" type.



    Data just seems to be more stable than functionality.

  • Going way back to Rebecca Wirfs-Brock and thinking about design from the perspective "Classes, Responsibilities, and Collaborations"... in most any large scale system there will be some objects performing "management" or "coordination" responsibilities, some are simply "information holders", some are "actors" that perform operations. Any project will have some domain modeling for the data, and then will divide "responsibilities for doing" among the domain objects and the managers, etc. Trying to cram all of the responsibilies into the domain objects or into the managers and actors probably means you've not got an optimal balance between cohesiveness and coupling.


Comments have been disabled for this content.