Archive

Posts Tagged ‘programmer discretion’

Bringing Plausible Deniability to Development: the Strategy Pattern

July 30, 2009 3 comments

July 30th 2009 | David Cooksey

Bringing Plausible Deniability to Development: the Strategy Pattern

If the template pattern is a benevolent dictator the strategy pattern is a politician concerned with plausible deniability: Don’t tell me the details, just do it. The strategy is defined solely in terms of its inputs and outputs.

Let’s say you are writing a program that cuts checks for employees. The code that handles the physical printing of the checks is complete, all that remains is determining how much to print on the check for each person. The company contains both salaried and hourly employees in addition to salesmen whose pay is based on commissions. Also, the company sends out holiday checks to all employees at various times of the year based on how the company performed recently.

You want to be flexible, so your payment generator is designed as a windows service that polls a PaymentRequest table periodically. It then examines the type of payment to determine how the amount should be calculated. The next step is to write and organize implementations of the different ways to calculate payments.

The design should be flexible enough that it makes adding new payment types as simple as possible, while also providing as much flexibility as possible with respect to implementation details. You don’t want to mandate that a particular step in calculation occur, because you don’t know what future payment types might require.

This is where the strategy pattern comes into play. You can use a simple interface that defines your payment strategy to streamline your code and cut down on the number of decision points. All you really need is a block of code that looks at the payment record and decides what strategy to use. The other code should be the same regardless of the payment type. Here is some pseudo code for what this would look like:

public interface IPaymentStrategy
  {
    double CalculateAmount(IPaymentRequest paymentRequest);
  }

public class PaymentGenerator
  {
    public void LookForPaymentRequests()
    {
      IPaymentRequest[] paymentRequests= GetNewPaymentRequests();
      foreach (IPaymentRequest paymentRequest in paymentRequests)
      {
        Process(paymentRequest);
      }
    }

    private void Process(IPaymentRequest request)
    {
      IPaymentStrategy strategy;
      switch (request.PaymentType)
      {
        case 1:
          strategy = new HourlyPayment();
          break;
        case 2:
          strategy = new SalariedPayment();
          break;
        case 3:
          strategy = new CommissionPayment();
          break;
        case 4:
          strategy = new HolidayPayment();
          break;
        default:
          strategy = new FlatPayment();
          break;
      }
      double amount = strategy.CalculateAmount(request);
      WriteCheck(amount);
    }
}

IPaymentStrategy defines a simple interface that accepts an IPaymentRequest and returns the amount calculated. The PaymentGenerator pulls in new payment requests from a table. It picks the appropriate payment calculation method based on the payment type Id and uses it to generate the correct payment amount.

If a new payment type is added, it requires no code restructuring other than the creation of a new class that inherits from IPaymentStrategy, a new case block, and a new row in the PaymentType table.

This code structure places no restrictions at all on the implementation details of the individual payment types. If a lot of code is shared among the payment types, inheritance, a common dependency, or any other method can be used to reduce or eliminate code duplication entirely at the discretion of the programmer.

This makes it easier to ignore the gritty details of payment calculation which a more strict pattern such as the Template Pattern would force you to consider.

Flexible

Maintainable

Plausibly Deniable

The Strategy Pattern.

David Cooksey is a Senior .NET Consultant at Thycotic Software, an agile software services and product development company based in Washington DC. Secret Server is our flagship password management software product.