Showing posts with label design. Show all posts
Showing posts with label design. Show all posts

Monday, October 20, 2008

The Anatomy of a Service (Part II)

With my last post, we began the journey into the anatomy of a service by restating the definition of a service in the context of SOA. In this post, we're going to dig a bit deeper into the elements that make up a service. These elements are illustrated below.


Note that the illustration above doesn't imply any kind of layering. There are three types of service elements depicted. The yellow elements are related to the service domain. This is the logic, information model and state that drives the behaviour of the service relative to the responsibilities it holds in the overall architecture.

The green elements relate to the service boundary. The service contract describes the messages managed by the service and the endpoints through which the messages are exchanged.

The blue elements are service resources. Note that the service contains human resources. This is because service logic may in part be executed by people. This is explained in more detail here. This is a very important point. Most discussions around SOA tend to describe services only as IT constructs. A service consumer is unaware and does not care whether the service functionality is provided by people at a keyboard or software running on a server.

In addition to the human resources, a service also will very likely contain software and hardware infrastructure. The hardware infrastructure refers to the physical hardware on which the service operates - e.g. servers, SANs and communication infrastructure.

The software infrastructure refers to software that supports the operation of the service, but doesn't implement the logic defined within the service domain. So for example, this software would include operating systems, application platforms and communication software.

The distinction between software infrastructure and service domain logic is an important one. Software infrastructure can be reused between services, whereas logic related to the service domain should not be. Domain logic should be implemented and deployed only once in one service. Why? Because otherwise we have low cohesion - a single concern addressed by multiple services - and that leads to coupling between services.

So why can we reuse software infrastructure between services? This is because such software is generic. It doesn't pertain to any specific service domain. Take UI rendering logic for instance. The logic required for rendering a window doesn't relate to any specific domain addressed by any service in your business.

Other examples of software infrastructure include rules engines and workflow systems. However the rules and workflows themselves would constitute service domain logic.

An interesting example is a CRM package. A CRM package comes with quite a lot of what would seem to be domain logic. For example, a CRM may be deployed in support of the Sales function of a business without a great deal of customisation. Here, a large number of the native application features will directly contribute to the service domain.

A CRM package does not however need to deal only with customers. Most CRM packages can be highly customised to hold custom entities with complex relationships. Custom logic can be added to the CRM package to implement specific business rules around these entities. In this case the CRM package is being leveraged as an application platform, and as such is not implementing the domain logic of the service.

Okay last but not least, we need to discuss the service information model and state. Pretty much every service will have state. That state will conform to the service information model and the service domain logic executes against that information model. To that end, the service information model, state and domain logic are all indelibly linked.

Note that any state leveraged by the software infrastructure is considered part of the infrastructure itself and not part of the service state in the above illustration.

Just like service domain logic, the service state and information model should not be shared between services as it introduces coupling. Services should share data only by way of message exchange, although this is not always possible when transforming an enterprise full of legacy applications to an SOA - at least initially; but more on that in a future post.

So everything in blue in the above illustration is reusable between services. The same people can participate in many services, and the same software and hardware infrastructure is reusable between services. Everything else should not be directly reused as it introduces coupling and reduces cohesion. Of course, domain logic within one service can be reused by other services through exchanging messages with that service.

Okay well that sums up the basic elements of a service. Stay tuned for my next post in this series!

Thursday, October 16, 2008

The Anatomy of a Service (Part I)

It occurred to me that to date I've been heavily focussed on defining SOA, techniques for defining service boundaries, contracts and responsibilities, and the various flavours of SOA that we see in the wild, without giving much attention to what goes on inside the service boundary. So I thought it appropriate to begin a series of blog posts on the anatomy of a service.

So let us begin by restating the definition of a service. A service (in the context of SOA) is an autonomous coarse grained unit of logic that exposes functionality by way of exchanging messages conforming to its service contract with service consumers via its endpoints.

The service contract describes the syntax (not semantics) of messages exchanged via each service endpoint, as well as the means by which messages are carried between each endpoint and service consumers. Each endpoint is located and uniquely identified by its address.

A service provider may also consume other services, and a service consumer may in fact also be a service provider. As such, the terms service provider and service consumer describe roles in a specific interaction. The rules governing communication with a service are described by its policy.

What do we mean when we say a service is autonomous? Well we mean a few things actually. Firstly, services are in control of their own state. Services are not instantiated by their consumers. A service exists as a single autonomous entity.

Secondly, we mean that services may be under different ownership domains. Those parties responsible for the service and its management may very likely be different to those responsible for other services. Services may be versioned and deployed independently of each other.

And thirdly, we mean that services should not be dependent upon the availability of other services in order to function without failure - even if that is in some limited capacity.

I'd also like to point out that there is the view that a service contract should not be devoid of semantic definition. There is the thinking that a service contract should also describe the semantics of the messages exchanged by the service, as well as the state the expected behaviour of the service.

Okay so now we've defined a service, what does a service look like? Well that's the beauty of SOA - because service implementations are encapsulated within their service boundaries, consumers don't (or shouldn't anyway) have any visibility or knowledge of the service provider's implementation.

But that doesn't really help us much as architects that need to design these things. That's the reason for this series of blog posts. We as architects need to understand the different ways to go about designing services - not just their boundaries and responsibilities, but their implementations as well.

Over the next few posts I intend to go through various different flavours of service anatomy in order to bring some clarity to the various options that exist for implementing services. So stay tuned!

Thursday, May 22, 2008

SOA Quality Spectrum

We've covered a lot of ground over the last month since I first proposed my definition of SOA, and I wanted to take the opportunity to do a bit of a recap and tie it all together by comparing and contrasting the various flavours of SOA discussed to date.

As I've previously mentioned, there are good SOAs and bad SOAs - with some considerably worse than others. So what are the typical metrics we might use in assessing the quality of an SOA? One might say it depends on the needs of the business the SOA supports. That is, an SOA is of high quality if it clearly aligns with and supports the strategic goals of the business.

Obviously every business is different. Even businesses that compete in the same market and service the same customers have unique characteristics. They have different organisational structures and business processes. Their distinctiveness is what gives them their competitive advantage. It is what differentiates them from their competitors.

Business strategy is heavily influenced by the external forces that operate on a business. Porter's five forces analysis is a good way of identifying these external forces and deriving strategies for gaining competitive advantage.

Regardless of the business and the market in which it operates, an organisation must evolve and adapt as the competitive landscape changes. The ability of an organisation to invoke change quickly, inexpensively and at low risk is a key factor influencing its success. It facilitates innovation and affects how responsive an organisation is to market forces.

Although there are many factors that influence business agility unrelated to IT, a machine is only as fast as its slowest moving part - and in many large organisations, that part is IT. For these organisations, IT becomes the bottleneck, resulting in the perception that IT is a necessary evil, always at odds with the rest of the business.

So what aspect of an IT architecture determines agility? Simply put - coupling. Coupling determines the extent to which change within one software component affects another. With a high quality SOA, a single change to how a business chooses to implement a specific business capability is isolated to a single service. As only the implementation has been affected, the service contract remains unchanged and consequently no other service is affected or even need know about that change.

So although there are other quality metrics that vary from business to business and industry to industry, agility is a key universal quality metric for an IT architecture. Based on this metric alone, I propose the following SOA quality spectrum.


I've included JBOWS, Service Oriented Integration, Layered Service Models and Self-Contained Process-Centric Service Models on the spectrum. I'd be interested to hear from anyone who has seen any other flavours of SOA out there that I've missed. I'm also interested in getting feedback from people who would propose alternative or additional quality metrics for SOA.

Tuesday, May 20, 2008

Layered Service Models are Bad (continued...)

In my previous post I introduced a couple of example typical business processes for an insurance company and illustrated how they translated to a service model based on process, task and entity services. After listing a number of shortcomings of this model, I promised that I would suggest an alternative service model that didn't suffer from the outlined issues.

As I previously mentioned, services should be centred around cohesive business areas/capabilities. We also wish to decentralise our data so that each service has the data it needs locally to service each request without retrieving data from other services. Furthermore, we want to rely mainly on publish-subscribe messaging in order to avoid the coupling introduced by command messages.

So our first order of business is to identify our cohesive business capabilities upon which we will base our services. Through analysis of the originally described business processes, there appears to be the following five cohesive business areas at play - Premium Quotation, Policy Administration, Commission Management, Billing and Customer Management.

Creating a service around each of these business areas gives us the following service model.


Firstly note the simplicity of this model over the model outlined in my previous post. There are only five services, and the dependencies between the services are limited to communication over three topics.

There is no need for any entity services as each service depicted in the above model houses its own data locally. Consequently we have no need for cross-service transactions.

The business logic previously contained in task and process services relevant to a given business area is now fully contained in the corresponding service. As a result, we have far improved encapsulation. Our data is protected from direct manipulation by other services.

The Policy Creation and Policy Reinstatement processes are now mapped to the above service model as illustrated below.

Policy Creation

Policy Reinstatement

Note also with this service model that we have no synchronous request-reply communication between services whatsoever. This results in a considerably more robust, performant and loosely coupled architecture. The high cohesion found within each service further contributes to the loose coupling.

We have coarser grained, business relevant messages exchanged between services and there are considerably fewer message types to deal with. And to top it all off, this service model will take less effort to implement and considerably less effort to adapt and maintain.

Monday, May 19, 2008

Layered Service Models are Bad

Open any number of books out there on SOA and you'll find guidance on defining the service model for your enterprise in terms of process, task and entity services. This in essence sets up three layers of services, with process services as the top layer, task services underneath the process services, and entity services at the bottom.

The purpose of entity services is to provide an abstracted view of business document repositories. The actual structure of the underlying data and the platform holding the data are abstracted into the form of entity service contracts.

The operations exposed by entity services are your basic CRUD centric operations such as GetCustomer, GetOrdersForCustomer, UpdateCustomer and DeleteCustomer.

Task services each represent a single atomic business action. Task services leverage entity services to manage state.

Process services are then created in support of business processes. Each process service wires up any number of task services in support of a specific business process. Process services can also "invoke" other process services when there are sub-processes to be reused by those processes.

Consider the following two vastly oversimplified business processes:

Policy Creation
This process involves the creation of a new policy. An underwriter uses a composite application to first go and get a premium quotation, and then if the customer accepts the premium create a new policy.


Policy Reinstatement
This process involves reinstating a previously cancelled policy.


Note that the Allocate Commissions and Raise Invoice tasks are "reused" between the Policy Creation and Policy Reinstatement processes.

Translated into a service model based on process, entity and task services, we get the following:


For those who follow this blog, you would probably guess that I'm dead against this kind of service model. There are so many problems with this model it's hard to even know where to start:

Transactionality: The task services must perform updates across numerous entity services. The task services are atomic in nature, which means that either the entire task must succeed or fail. This means we need to have cross-service transactions between entity services.

As I've explained in previous posts, cross-service transactions are bad for performance reasons and because they hurt the autonomy of services. One entity service can have records locked while waiting for another entity service to either commit or rollback its local transaction. One entity service can heavily influence the execution of another.

Performance: As mentioned above, cross-service transactions hurt performance. However, the other thing to notice about this architecture is that it is full of synchronous request-reply communications. This approach simply does not scale.

Robustness: As I've mentioned previously, synchronous request-reply interactions between services seriously hurts the robustness of your architecture. If one of those entity services goes down, you can pretty much say goodbye to a large number (perhaps even the majority) of systems in your enterprise.

Cohesion: With this service model, multiple services deal with very similar business concepts. You have the same entities being managed by multiple services. You have multiple task services dealing with the same entities. This means you are likely to get considerable duplication of logic and information representation between services.

This means your developers need to write considerably more code. Furthermore, the communication between services is likely to be very chatty, involving a large number of finely grained messages.

This in turn means greater coupling between services. This results in even more code to be written in order to handle the vastly increased number of message types. In essence, the proposed services in this model are too finely grained.

Coupling: As mentioned above, the low cohesion between services means greater coupling. You also get temporal coupling as a result of all the synchronous request-reply communications.

Complexity: There are simply too many services defined in this service model. With this approach, you will likely end up with hundreds or even thousands of services supporting an entire enterprise - each with dependencies to be managed and understood.

Encapsulation: By exposing data directly via entity services, any service can update any data in whatever way they see fit. This results in very poor encapsulation. We want our data to be surrounded by business logic that enforces our business rules.

Service Contract Stability: The implementation details of cohesive business processes are exposed in the service contracts of the task and entity services. As the needs of the process services they support change, the service contracts will need to be updated. I'll cover service contract stability in another post.

People are usually allured into using this kind of service model by the promise of reusability. That is in fact the fundamental premise of the architecture - that process, task and entity services can by simply reused by dropping boxes that invoke those services onto a process orchestration design surface.

However as I've previously discussed, the promise of this kind of reuse is false. It is all very good in theory, but as usual the devil is in the detail and you simply don't get this kind of reuse in practice.

In conclusion, services should be self contained; aligning with cohesive business areas/capabilities. The concerns of a single cohesive business capability should be supported by a single service. Not by many process, task and entity services.

In my next post, I'll describe the service model that I would suggest to support these business processes, so stay tuned!

Sunday, April 13, 2008

Design before Technology

Design patterns for the most part are technology agnostic. They capture a best of breed approach for solving a problem in a particular context. Technology is an enabler of these design patterns. We use technology to implement the solutions the design of which is based on design patterns.

Design patterns evolve must more slowly than technology, and are rarely made obsolete. New design patterns arise to face new design challenges and to better manage complexity, whereas new technology arises to make the implementation of these designs easier such that they can be done at lower cost.

Technology led architecture is a recipe for failure. In this situation we see architects designing solutions around some new technology being pushed by some vendor. Where we tend to see this most is ESB driven architecture. Businesses are told they must have some expensive piece of middleware to make their SOA reality, but then the implementation fails due to a lack of proper planning and design.

This is why it is so vitally important for SOA practitioners to be well versed in the theory and best practice of SOA rather than simply being trained in the use of one or more middleware products. A middleware product in the hands of an architect without proper understanding of the guiding principals of SOA is very dangerous indeed.

The architecture must come first and be based on the business requirements and business context, guided by design patterns. The technology must then be selected to support the architecture. This way we ensure that the selected technology is appropriate for the solution.