Object Oriented programming has served us well and will continue to do so. In the case of a SOA, this would imply to only inside the edge, the so-called boundary of my service. Once outside the edge, we need to think in terms of messages. Messages, unlike objects don't have methods.
I have seen too many implementations try and send Business Objects over the wire, only to notice that the business rules in the object did not make it across the WSDL. So to de-serialize the BO's and have them contain methods, we need to modify the client proxy and use a shared library so the server and client can refernce the same BO library.
At a first glance this seems like a rocking solution, but we have just violated the very essence of SOA, loosely coupled components.
Another challenge with BO's is inheritance. While WSDL 2.0 does support the notion of inheritance, again we need to move away from the OOP concepts for the edge.
The Java community often refers to DTO, Data Transfer Objects, to describe a object or structure that contains only data fields, no methods. This is the closest analogy I can think of between the messages of the SO world and objects of the OO world.
So suppose we buy of on this idea, how do we provide tranditional BO like experience in the SOA world? The short answer is, we dont. Having said this, I have seen implementations where the client exposes a BO type interface, and have the BO internalize the service proxy to do all the service calls.
So a call to User.Save(), will internally call the coresponding method on the proxy and service. Personally, I would not go this route, as this hides the fact that we are crossing a boundary and developers may not understand all the implications involved with that single statement.
Secondly the definition of the User object lives inside the client app domain. A similar user object may in fact be exposed by the service (WSDL) and generated by the proxy, so we may be duplicating the entity.
My preference is to create a Business Facade layer, wrapped around the proxies. Instead of calling User.Save(), we would call UserFacade.Save(aUserDTO), or UserDTO user = UserFacade.FetchUser(userId) etc. Hydrating the UserDTO and passing it to the Save method, just seems more aligned to the fact that a message is constructed and will be passed over the wire. I most cases the UserDTO may be the very object generated of the service WSDL.
Boundaries need to be explicit and developers should not be shielded, in constrast with DCOM, of the implications of network latency, out-of-process execution etc.
Having this extra layer of indirection allows us to swap out services, without impacting the rest of my client code.
OOP still has a huge role to play inside the edge, but we need to learn to think in terms of message when we are sending packets of information across our SOA.
No comments:
Post a Comment