Monday, August 28, 2006

SOA and OO its not just data shifting

One of the biggest disappointments that I've had in reviewing Java projects is the death of Object Orientation, sure we have "Customer" as an object but its just about data shifting rather than the objects representing both data and behaviour. The rise of Web Services and the tooling of these is actually making this situation quite a lot worse. So when all of these tools generate objects from services they generate data shifters. The phrase POJO is held up as a good thing because POJOs are simple, and in someways they are, but the question is are these objects becoming far too plain? Logic that was in previous generations hidden within the object is now isolated within classes that could easily be mistake for C programmes, i.e. they just do data processing.

Lets split objects into a couple of layers of intelligence

The data shifter - Basically a C structure in a class file

This is the worst case where the object has just been generated and is a series of get and set methods with precisely zero behaviour, unless you count assignment as behaviour (which I wouldn't). Here you aren't getting any real benefits of using an OO language, as much as you pretend your code is OO its really C code in class files.

Valid fields - Taking the C structure and turning it into Ada

This is still really just procedural code but at least using Ada rather than C. At this stage the XML Schema/Database restrictions have been applied into the generated objects so you can only set valid values into the object. So if you try and set age to "-1" then an exception is thrown calling you a muppet. This level should be the very lowest that a system should stoop to.

Valid Object - Object assures its integrity

The next stage is where the object starts doing more complicated rules, like checking that "Date of Birth" isn't in the future or that "Total" isn't a field its actually a function that adds up all the elements in the "OrderList". This is a good place to be starting from, I've seen several times cases where Order "objects" have a "Total" field that was passed from a Web Service along with the order line and then the total field becomes... well bollocks.

The reason these problems happen is that on one side of the equation (lets say Service A) there is an objection something like

interface Order{

public int getTotal();

public List getOrderLines();

.....

}

and the implementation of getTotal is something like

int returnValue = 0;

for(OrderLine nextLine : this.orderLines){

returnValue = returnValue + nextLine.getValue();

}

return returnValue;

When the WSDL is generated this creates two elements "total" and "orderLines", on the otherside this is the imported and of course the dumb IDE has no clue that total is a function, it just knows it has a value, so now you have a case where while the interface is the same there is now a get and a set function and they both just do an assignment to a class variable.

So when generating these objects you need to make sure that the fields shouldn't really be functions. It would of course be great if there was a way of describing this relationship within the XML document, so it was automatically generated.

My Object - OO designing on both sides

Now the best place to get to would be a recognition that maybe the needs on both sides around behaviour are actually different. The basics around validity will be the same, but the behavioral aspects of the object will be different. So if I'm a supplier of widgets and I work with a supplier of doo-hickies to produce ooojamaflips then my "Customer" object needs to have a "validate" method which checks that the customer doesn't have any outstanding bills, and it makes that check on my local systems. Equally the 4PL that we use to do the assembly needs to check "validate" on customer against its own systems and also needs to have a "notify" method on the order object that sends a message to the customer as its stage and position changes through the supply chain.

SOA doesn't replace OO as a good practice, and the fact that SOA tools generate base classes that are thick is pig-shit doesn't mean you should use them directly. There are wonderful mechanisms in OO like "inheritance" which can enable you to extend these objects with your own service specific behaviour. The piece that should be industrialised is the bit upto "Valid Object" as these rules should be integral parts of what the object is meant to represent. It really is ridiculous that people are still waiting till a database violation occurs before checking that the data is right.

I had a crack with obligate at doing some of the validation stuff, but its custom and not generated (yet) and a bit of a pain for objects. Hibernate has some bits around data validation which is pretty nice, but doesn't really do valid objects yet, and of course is database rather than Service/XML driven. Its one of the sad facts about IT that we appear to take a leap forwards and lose some of our valuables on the way. It will be interesting to see if OO continues to wane or if generally people start realising that OO lives inside the service and that the old OO rules, and benefits, still apply.

Technorati Tags: , , , ,

5 comments:

Anonymous said...

+1 on your OO comments for implementation design, but: I don't see how you can reasonably argue for transfering objects at service boundaries.

Steve Jones said...

I'm crap at English, its only my native tounge! I don't mean you should transfer the objects, but that the core validation (which hopefully should go into the XML Schema) which says that the object is valid should be transfered and that ideally you'd like to transfer functional associations of the data (like total being a function not a value).

What I'm saying is that the current "generate a completely basic data shifter" should really "generate an object that actually is valid"

So you should still be loosely coupled, just using the XML Schema as a common definition of "valid".

Anonymous said...

I would first say that this post is true regardless of SOA. Good OO design is based on encapsulation of data with behavior. SOA should definitely NOT be implemented in such a way as to change that. If the tools available today do violate good OO principles, then we'll need to work around them.

Stefan, I'd say that the use of service agents and message handlers wrap the messages that go between services, leaving boundaries object based. I say "based" and not "oriented" because interacting with a service is quite different from an in-memory object - or at least, it should be (network latency and all that).

Anonymous said...

If you're argueing for ensuring the validity of documents passed at service boundaries through XML Schema or RELAX NG + e.g. Schematron, I agree. But still, I believe that to a certain degree, the SOA principle of exchanging document-style messages puts an emphasis on data that would be deemed bad design in OO -- which I don't have a problem with.

Anonymous said...

Its a very nice blog for...
architects in bangalore , architects in bangalore , interior designers in Bangalore , interior designers in Bangalore , architects in bangalore , architects in bangalore , interior designers in bangalore