Architecture – How to loosely couple modules in service oriented architecture

Architecturecouplingnetservicessoa

We're developing a total solution, and we've chosen service-oriented architecture to loosen subsystems. However, now we have a problem.

When customer orders something, Order Subsystem is responsible to get that order, and register it. However, there are some other modules which are responsible too, in order registration process, and each module should do something on it:

  1. Customer Accounting module should check customer's balance, and prevent order registration if there is not enough money in customer's account.
  2. Asset Management module should increase/decrease customer's assets
  3. Rule Engine should apply some business rules dynamically on it (like preventing a specific customer, or notifying an operator, etc.)
  4. CRM should view customer's history, and give good customers some discount

Right now, we're doing it this way:

public void RegisterOrder(Order order) 
{
    RuleEngineService.ApplyBusinessRules(order);
    // some code here
    CrmService.GiveDiscountIfApplicable(order);
    // some code here
    CustomerAccountingService.CheckBalance(order);
    // some code here
    AssetManagementService.ChangeAssetCount(order);
    // some code here
}

This means that if we add another subsystem (module) that needs to do something on order, we have to recompile the code of our OMS (Order Management System) to support it. Also we're coupled to some extent to other subsystems here, and if one of them fail, this registration process fails.

One way of making this piece of code dynamic and loosely coupled is to use interfaces or contracts, like:

public void RegisterOrder(Order order)
{
   // Finding a list of all IOrderProcessors.
   // Looping over each, calling orderProcessor.Process(order);
}

However, it has two problems:

  1. We can't use interfaces over SOAP and HTTP (we don't have access to other subsystems' DLL files)
  2. Those need to run in a specified order (rule engine the first one)

What should we do here? What are the known patterns and practices?

Best Answer

Take a look at the Pub-Sub pattern as it's well suited for providing that decoupling you're looking for. The observer pattern may have some applicability in your case as well.

In essence, the "main" application that handles the request will push a message to a queue that the other systems will pick up and handle as they need to. You'll need to define a standard interface or contract for the message format, but that's what will gain you the decoupling you're looking for. Adding and removing applications is as simple as adding and removing subscribers.

Another added benefit is a supporting system can go offline, and when it comes back it will pick up where it left off in the message queue.

If you have atomic transactions, you'll need to extend the pattern a little bit. Reply messages on another queue are one means of accomplishing that. Presumably you already have some logic in place to handle that transaction state, so you would just need to modify it to react to reply messages instead.

Related Topic