Context and Facets

A part of designing a method-based system is detailed design. So, once you have defined the service components, it is time to define the contracts.

Context

In searching for volatilities in your system you have probably found some parts that depend on the context in which they are executed. What does that mean?

How I like to explain it is, that context is about achieving the same result but from a different perspective. Like canceling a doctor's appointment.

Imagine a healtcare manager contract with the following operations:

public interface IHealthcareManager
{
  Task<CreateAppointmentResult> CreateAppointment(CreateAppointmentRequest request);
  Task<CancelAppointmentResult> CancelAppointment(CancelAppointmentRequest request);
}

Canceling an appointment in the context of a patient is likely to be different than when the doctor's assistant cancels the appointment. And with different I mean; it will involve less or more steps in the process. One obvious difference in the cancellation of the appointment by the doctor, is that the patient has to be informed and the appointment has to be rescheduled.

Context can be supplied separately from the method call. Like a security context that is passed in the header of a message, or a user context that is fetched via an authorization token. 

Then, based on the context, the operation will perform less or more steps to complete.

There are several ways to supply the context, which I won't address in this post. That's something for a future post.

Facets

You do not want a service to have too many operations. This is not maintainable. A facet can be used to reduce the number of operations of one (God) contract. It is about separating use cases that do not really belong together but are executed by the same component/service.

For instance, the healthcare manager handles appointments on the one hand, and can find a qualified specialist/doctor for a patient's ailment on the other.

This leads to two facets. The IHealthcarePlanningManager and the IHealthcareMarketManager. And you can probably guess, the planning manager is all about handling appointments and the market manager is all about matching patients and doctors.

The end results

In this example the manager will have to implement two interfaces. The client will call the service by one of the interfaces.

Service

public class HealthcareManager : 
IHealthcarePlanningManager, IHealthcareMarketManager
{
  ...
  public Task<CancelAppointmentResult> CancelAppointment(
    CancelAppointmentRequest request)
  {
    var strategy = _strategy.Find<IHealthcarePlanningManager>(_context);
    return await strategy.CancelAppointment(request);
  }
  ...
}

Client

public class HealthcareClient
{
  public async Task<bool> CancelAppointment(guid appointmentId)
  {
    var proxy = _proxy.For<IHealthcarePlanningManager>();
    var cancellation = await proxy.CancelAppointment
    (
      new CancelAppointmentRequest(appointmentId)
    );
    
    return cancellation.Approved;
  }
}
Leave me a comment about what you think.

Comments

Popular posts from this blog

Google Releases Chart Image Generator