January 17, 2008

...Learn TDD with Codemanship

SOA Dependency Management Principles

If you're a student of software design then you might be familiar with a design principle for object oriented software called Liskov Substitution*.

Barbara Liskov surmised that you must be able to substitute an instance of any type with an instance of any of its subtypes. So we must be able to substitute a SettlementAccount for an abstract Account, for example. Any clients using Account should not suffer any ill effects from the substitution.

What this means is that we must ensure subtypes satisfy the rules that apply to all of their supertypes. This is important to help us manage dependencies and limit the propagation of change within our software.

A closely related design principle is called the Open-Closed principle, which states that classes should be open to extension and closed to modification, so we can substitute extending classes without having to change the code depending on our original base class. This only works if subclasses obey the rules of the base class, and so Liskov Substitution is a requisite for Open-Closed.

And so is the ability to extend classes, of course. languages that don't support polymorphism make substitution impossible.

Why am I telling you all this? Well, it's all about web services, you see. In a meeting this morning, we grappled with the problem of versioning web services and minimising the impact of changes within our enterprise architecture. And here I am banging on and on (and on) about unifying the principles of dependency management at all levels of design, and surely that includes the system/service level, too?

In which case, the 3 core strategies for managing dependencies should surely still apply:

1. Reduce the number of dependencies between units of code (e.g., methods, classes, packages, systems)

2. Encapsulate dependencies inside units of code (e.g., put fields and the methods that access them in the same class)

3. Depend on units of code that are less likely to change (e.g., depend on abstract classes or interfaces)

So we should first strive for systems that are as loosely coupled as possible, meaning fewer web service calls between systems. And we should strive for systems that are as cohesive as possible, which means putting services in the same system as the data they act on. (See my post about Lack of Cohesion of Services) And finally, we should favour dependencies on web services that are less likely to change. I'm not entirely sure what that means at this level. Is there such a thing as an abstract web service? Can web services support polymorphism in the same way classes and interfaces can in code? I'm not an expert in the technology, so I don't know how this could be achieved - or, indeed, whether it can be achieved at all. This is something I'll have to look into.

And there are probably other design principles that apply, to SOA, too: like Interface Segregation. If client A uses web methods WM1, WM2 and WM3, and client B uses web methods WM4 and WM5, then arguably there should be too seperate web services, one exposing WM1, WM2 and WM3, and the other exposing WM4 and WM5. That way, if a change is made to the first web service, client B doesn't need to change at all. This, too, could help mimimise change propagation.

* Not to be confused with Pavlov Substitution, where you ring a bell and your cats start salivating

Posted 13 years, 5 months ago on January 17, 2008