Skip to end of metadata
Go to start of metadata

Goals

Extend an existing, distributed system without compromising scalability with acceptable cost (time/money). The most important drivers are maintainability and reuse/cost.

Context

We have an existing distributed system where service A uses a service B, which in turn uses a service C. Let service C be responsible for communicating with a certain type of hardware. We now want to add support for a new type of hardware device. The producer of this hardware device offer software to communicate with the device.

Full Size

Strategies

We have the following options:

1. Extend the existing services to support the new hardware
2a. Modify B to support services C 1, C 2, C 3...
2b. Modify A to support services B 1, B 2, B 3...

The traditional (pre SOA?) approach is to use option 1. This might or might not be appropriate. In the case where service C is tightly coupled to a specific hardware unit, it seems natural to add more services instead of changing existing ones. The goal is better scalability and better separation of concerns. Below explains two such strategies based on option 2.

System extended at level C

Let us rename service C to C 1 and let C 2, C 3, C 4 denote services that support new types of hardware at the same level as the original service C. This option might require some changes to service B, but service A can probably be reused as it is. This is the cheapest and probably the best option.

Full Size
System extended at level B

Producers of new hardware units often sell their hardware bundled with software to use it. Reusing this 3rd party software might reduce development time, which can be enticing in terms of cost and/or time to market. "Unfortunately" the producer has written functionality that partly overlaps functionality found in our service B.

If the 3rd part software, D 1, can function as a C-level service, that might be the best approach.

If it cannot, we are forced to let it communicate on the B-level. We should add a wrapper/bridge/adapter/anti-corruption layer/whatever between D 1 and service A, to avoid having to change service D 1 or changing A. It might seem logical (and easier) to change service A, but changing service A does not scale very well. So when you add support for more hardware ( D 2, D 3, D 4...) you have created an unmaintainable blob of code. Instead we add a separate service/component to handle the differences between the interface of A and the interface of D 1 to separate concerns and make the system as a whole easier to maintain and test. That is, B+C are needed to allow A to communicate with hardware units of a specific type. D + some extra code is needed to add the same support to another type of hardware unit. B+C is thus analog to D + some extra code.

Full Size
Conclusion

When adding support for multiple "types" try to use abstraction to mask the diversity as early in the chain as possible. (Note that this advice is as valid within a service as between services.) The less parts of the system that needs to handle diversity the better.

Labels:
None
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Sep 24, 2008

    Hmm.... service versus component is like object versus class....

  2. Oct 21, 2008

    Writing hardware abstraction layers (HAL) is an old technique that has been used for decades before SOA was coined, so I don't agree at all that strategy 1 was the traditional way of adding support for more hardware devices. Component C should implement a HAL if there is a requirement to make it easy to support different types of hardware devices. See for instance: http://en.wikipedia.org/wiki/Hardware_abstraction_layer

    I also find the title of this pattern not very descriptive - I would suggest to name it "Hardware abstraction layer"

    1. Oct 21, 2008

      Thanks for the comment. Understanding how others interpret this "pattern" is really useful.

      I'll read up on HAL,but as far as I remember the pattern this is not about HAL. It is about the components that communicate/use the different HALs and at which level we should enforce specific domain model abstractions.

      Perhaps it makes sense to describe which parts of the model corresponds to HALs?

      1. Oct 22, 2008

        Or just change the example to not use hardware units as a key element in the example, as it confuses old-school HAL enthusiasts? (Or just retrofit the HAL concept as a footnote...)