Archive for Technology Migration

May
18

Software Wallpaper

Posted by: | Comments (1)

kick it on DotNetKicks.com
When I was growing up I spent a lot of time with my father doing woodworking.  One lesson you pick up pretty quick when woodworking is that you have to keep the work clean at each step.

sanding

  • If you take a piece of wood and don’t sand the surface smooth it won’t take a stain evenly.
  • If you let glue creep out of the joint and get on the wood, the stain won’t look right in that spot.
  • A piece of dust on the surface will get magnified by each layer of varnish.

Each layer depends on what’s underneath it.  Any flaw in a lower layer will tend to get magnified and distorted by layers above it.

Whenever I get involved in enterprise architecture I get reminded of this analogy because I often run into irrational exuberance that you can add a layer to an existing system and paint over the flaws underneath.  I was involved in a few projects like that early in my career:  It was too hard to talk directly to the mainframe from the web server so you put a layer in front of that.  There was already a C++ layer doing a DCE RPC gateway, but that was also too hard to program against for large use so we added a COM interface to the DCE RPC gateway.  We made some prototypes and validated the concepts and charged in full bore, only to run into big delays and teething problems near the end of the project trying to get everything polished up and suitable for production.

The problem is that at each turn you may be making the developer’s short term life easier by giving them an interface more natural to their preferred programming environment but since it just builds on the layers underneath it will end up with all of the limitations they have – and they can show up in the most surprising places.  For example, we ran into problems where certain input would cause failures which we ultimately discovered was caused by % being used as an insertion marker in a gateway library several layers underneath what we were doing – so at best it would drop the % and the following character, but at worst you’d get back a random data element if you managed to create a valid insertion name.

Layering issues are particularly problematic because they tend to be data sensitive and highly situational depending on how the various layers interact.  This means that it’s very difficult to design a comprehensive test plan:  The system can act as if it’s nondeterministic, making it infeasible to state with certainty that the various modes of the software have been demonstrated by a test plan.  At best, you can say that it worked for the exact test inputs it was given.  When you do have a problem in production, the multiple technologies in multiple layers can make it particularly hard to debug because it requires a lot of chairs around the table to hit all of the possible players.

Are you decorating?  Or covering up the problem?

Whenever you’re part of a team proposing adding a new layer over an existing system to fix its problems or adapt it to a new situation, you should be suspicious.  Is this really the right path to make the API look right?  Or are you temporarily covering over a problem?  If it’s the latter, it’ll just show through later – and now you have two problems to deal with not one.

floral-wallpaperThere are good occasions to add a new layer:

  • To smooth technology upgrades: When you are shifting technologies, say from COM to .NET, you may want to create a custom layer as a new standardized interoperability adapter which will let you separate the upgrade problem into phases and handle them independently.
  • To support multiple technologies: Sometimes you need to support multiple types of clients – varying either by environment (say Java and .NET) or major architecture (say Client/Server and Web sites).

And a few suspect ones:

  • Mitigate architecture risk: To isolate a new subsystem architecture from the main codebase. We’ve heard this one before – you want to try out something new and iffy, like say Entity Framework.  To contain the risk, you want to introduce a layer between it and the rest of the platform so if it all goes bad you can easily swap it out.
  • Impedance Mismatch: You need to interact with something, but just don’t like the way it works. Perhaps it throws around ADO.NET recordsets and you prefer to work with strongly typed objects.

If you find yourself in one of the suspect scenarios, you should seriously question whether the work you’d do to create and validate a layer is really forward progress or just yak shaving.  Before you go down the path, you should seriously estimate:

  • Fixing the underlying problems: If the underlying layer(s) aren’t doing what you need, what would it take to get them changed (in the technology they’re currently in) so you could work without adding another layer? That puts the responsibility where it belongs, and keeps complexity under control. Do a full estimate of this approach.
  • Make a parallel layer: If you ignore the powerful aversion to creating duplicate routes to the same data, what if you created an alternate path to the underlying information. It may be that you bypass all of the layers or just some of the layers (such as down to the stored procedures that call the database). While this creates duplication, it lets each platform work in their own optimal way and allows for deterministic testing.
  • Using the existing layer as it is: It’s easy to overstate the impact of reusing a known system with issues. There’s a natural tendency to not realize that you’re comparing a well understood but flawed system with an unknown solution with unknown problems. Trading known problems for unknown problems makes everyone happy at the start of a project, but creates significant project risk downstream.

Put down the shovel and back away

When you create a new layer on top of existing layers you are often digging your project into trouble, both now and downstream.  In addition to problems with each layer creating a leaky abstraction, deploying and supporting these highly layered systems is extraordinarily challenging.  It becomes prohibitively expensive to make changes in lower layers because of the high chance of unexpected side effects showing up as defects in dependent applications.  More often than not, each layer has to be held static with any changes accommodated by creating new queries or items at each layer to be served in parallel with the older methods.

Before you go ahead, be sure you look at the total lifecycle cost of that decision, including support and maintenance.   Have a good or bad experience with putting up some software wallpaper?  Let us know in the comments!
kick it on DotNetKicks.com

Comments (1)