Published
Wednesday, April 23, 2008 9:12 AM
by
martin
In my years at Microsoft, I spent a lot of time in the performance and scalability lab, helping developers to achieve the maximum amounts of performance and concurrency in their applications. Because of all that experience, for me, it's a no-brainer that to make software systems work well you have to depart from your elegant OO-design at some point and start accommodating the specifics of your chosen implementation platform. I don't think this is obvious to everybody.
As a consultant, I've encountered some excellent OO designers and software architects who created OO models of their systems. Those models might well have been perfect in every way. Nevertheless, none of the mainstream platform vendors has yet perfected a way to execute those object models in ways that would be useful to our customers. Why is that? Because it's hard. Why is it hard? Because turning an OO model into code that will actually work well on a given platform depends on a highly-involved, intellectually-challenging process that developers carry out on a daily basis. Not to mention that it depends on information most people don't put into OO models, such as "where is performance most important: looking up the customer, or saving the customer's details?"
So I'd contend that the meaty part of a developer's job is actually figuring out how to make something work well on their chosen platform. OO models are an excellent piece of documentation that enable teams to share one view of their system. I'm all in favour of that, and there are other views of their system that developers could usefully share too.
You can look upon this as having to "spoil" a clean, elegant, model. But I could also say that a clean, elegant, model "spoils" a finished application if it doesn't work very well on your chosen platform. In most cases, the customer pays for the app, not the model.
I remember working with COM+, and MTS before it, where the platform dictated that you factored your code into COM objects based on their transactional requirements. Now, you could make those objects the same as the ones in your OO model, but if you did, performance would suck. Doing it well meant accepting that object factorization had real meaning to those platforms, and working with the platform instead of against it. The .NET platform is rather more forgiving. These days I don't think there are many sacrifices that have to be made to accommodate the platform, but I'm sure there are still some.
And it's not just about accommodating the platform. What about accommodating your team? You might very well choose to "spoil" your model so as to factorize the system in such a way that a team of people, maybe geographically dispersed, can efficiently collaborate on its development.
Developers have long been aware of the perils of a project plan. We've all worked for project managers that print out the plan and say "this is the truth, anything else is your mistake". In reality of course, the truth is what's in your version control system, and the plan is history as soon as it's been printed. That's not to say plans aren't useful. Clearly they are very useful, as a statement of where the team thinks it's heading.
I believe that OO design diagrams are very similar. Enormously useful as a shared vision of where the project's going. But probably inaccurate shortly after they've been distributed. The big difference is that project managers usually rehash the plan to accommodate new knowledge about the project, such as a specific task taking longer than expected. Designers seldom go back and change design diagrams to reflect code that's already been written.
This post is longer than I expected. I suppose it's turned into a treatise on the place and purpose of OO modeling in modern software development. 