Monday, December 18, 2006

Don't make your domain objects serializable

A while ago I blogged about the dangers of serialization and I mentioned there that serializing your domain objects is bad. I wanted to follow that up with some details on why it's so dangerous, and briefly mention a different approach. Technologies like web services make it real easy to start serializing objects and then send them to and fro - so serializing an Order object on the server and then sending it to the client application. Simple - I can just write my client app to operate on the domain objects directly, and then send them back to the server. What could go wrong - I can almost pretend it's not a distributed system. People talk a lot about decoupling but an area often neglected is coherence, in the case of many systems this means putting the business logic that operates on domain objects in the same place. It also often implies ownership - a particular server or tier in the application owns the domain objects and is responsible for mediating access and acting upon them. So why is coherence important? Suppose I've allowed my Orders, say, to be serialized and sent to others parts of the system. This may not seem important to start with - but as soon as you get multiple components able to change domain objects then synchronisation becomes a big issue. If a component updates it's copy of an Order at the same time as someone else (who also has a serialized copy) then we are going to need some kind of conflict resolution on the server side to work out what the final state of the order should be based on two (now different) copies of the same order. Systems like this have no clear concept of ownership nor, quite often, a clean model of an object's state at any one instance of time. All too often projects using this approach burn a lot of time trying to create fancy conflict resolution algorithms. Requirement change also becomes a problem, when you serializable domain objects it's very difficult to avoid distributing the business logic. That is manageable to start with, but as you add more functionality or change existing code you need to keep track of all the different components where that change may have impact. The business logic becomes 'smeared' across the system - coherence has been destroyed. A tweak to UI changes the Order object, necessarily because the serialized Order object is being use directly in the UI. A seemingly small change on the server side breaks all the client apps. We may have used some nice messaging technology and thought we'd ticked the 'decoupled' box, but we've coupled our components together as tightly as if we'd just done RPC. If you don't keep an eye on both coupling and coherence you'll end up with a messy system thats hard to maintain and change. So what can we do instead - I still need my components to do things with Orders. One way to model this is with a document centric approach, the objects sent between components are documents describing the changes we'd like made to a domain object. The documents are received, the business logic applied and some sort of a response document is returned. If some other component's request is processed before mine I'll get a response back saying the domain object was in the wrong state - requests are processed one at a time, there is no complicated conflict resolution. I can change both the domain objects and the business logic on the server as long as I respect the clear document based interface I have with other components. We have drawn a clear boundary around a service, the service manages the domain objects and I can request services by sending documents and receiving responses. Thinking about requests modelled as documents which are then sent to the appropriate service is, to my mind anyway, a much clearer model for a distributed system. It's certainly one I've found makes delivering complex distributed systems slightly easier to model, understand and deliver.

Wednesday, December 13, 2006

Commodity products for commodity business?

As a consultant I often find myself asked about build versus buy decisions, so should a client buy some off the shelf product or build some custom code? There are lots of questions around technology and testing which we need to ask, but I think we need to start with something a lot more basic. Is the project about differentiating the business? If you just want a standard HR system, say, which does the same as everyone elses HR system then just go and buy a product. It's the same HR system as all your competitors use, but neither you or they are differentiating their business using this system. Spending a lot of money building a custom system is not going to bring in new customers or generate new revenue opportunities On the other if the project is to enhance or build a key offering for the business then choosing a custom build might be the right way. In these circumstances if you choose a product you are going to struggle to differentiate yourself in the marketplace, especially if the competitors base their offering on the same product. In fact if they are not using it yet they can go out and buy the same product and match your offering. If you want differentiation then custom build can let you create a unique offering that would require significant investment from competitors to match. What about customization of products? But hold on, can't I buy a product, customize it and then create a compelling offering for my customers that way? Of course the answer is yes, but how much customization do you need if your competitors are using the same product? Product companies typically drive their feature set based on their client's customisations and enhancement requests. You then end up paying for these upgrades, you and your competitors are in effect funding a product company to keep a level playing field. In fact my experience has been you end up embedding custom written code (c#, java, etc) inside of the product to deliver those features which are truly valuable - those features which no one else has and which can make a compelling offering. Specialist skills? Of course product companies are on hand with training courses and consultants who can come in and assist, all for a reasonable fee of course. In fact for many product companies the consulting side of their business is hugely important, both from a sales and revenue generation point of view. Internal technical people are often happy to get on the training and acquire marketable skills as well, they know this is the kind of specialist knowledge people will pay a lot for (Resume Driven Development). So why do people pay top dollar for people who know particular products? Supply and Demand - There is limited supply as only so many people know the product. There is plenty of demand, companies have based their key market offerings around the products and desperately need people who can support and enhance them. If you really want a compelling and unique offering for your customers then consider custom build. If there are things everyone in the market does that give no competitive advantage then just buy a product.

Thursday, December 07, 2006

The Risks Digest

Everybody in the software industry reads this already, right?

Monday, December 04, 2006

Abstraction is a confusing word

This post by Jimmy Nilsson reminded me of some conversations I've had recently about abstraction. It's not a term that I like, not least because when it's used in relation to code I struggle to find real guidance in it. It's certainly a term thats used a lot in software, I wonder if we really have a shared understanding of what we mean when we use it? Some words I prefer are 'readable' or 'understandable', these seem far more concrete (forgive the pun) and are things I can more meaningfully provide people feedback on (or receive it!). I don't think I've ever said 'hmm, you need to make this code more abstract'. Maybe what we are looking for is generalisation - I do know that I've said 'if we make this code more general it could support these other types of order' Surely it is ok to capture just enough shared understanding such that the code you are writing will do what your users want, and then stop right there, why make things any more abstract than that? In fact this isn't really abstraction, at least at the high level, there may be abstraction going on lower down (around creating a class to represent users, say) but at the problem solving level we are often engaged in specialisation. The counter argument might be reuse, if the code is too specialised we might not be able to reuse it. Here again I think generalisation is a better word than abstraction. Do you want a general framework for connecting to databases or an abstract one? Reuse needs to be considered carefully, a common trap in software projects seems to be spending a long time building an abstract framework instead of focusing on the specefics of a client's problem. I think when people talk about abstraction are often trying to summarise the process of how we go from a problem in a particular domain to a solution that solves the problem, some people use the term 'knowledge crunching' one I personally find a lot easier to understand. Finally I guess my dislike of the term might also be influenced by people taking it too literally, so from code no one understands to needing a week of workshops around 6 months worth of UML just to try to relate it back to the problem at hand, abstraction in software projects can often be a source of pain.