Category Archives: Api Design

Policy-based ValueCache

In one of my last posts I analyzed how policy based class design could look like in C#. It turned out that policy based class design can help decomposing functionality which would usually be implemented in one class into smaller parts (policies). Those can then be put together (configure) in different combinations in order to compose one class which fits exactly the user’s current needs. In this post I want to work on a policy based class which provides caching functionality for one single datum.

 First I want to differentiate between 2 approaches declaring a cache of data as outdated:
  • The cache does not know when its data “runs out of date” and therefore uses some heuristics or strategies to determine that. For example a common strategy to declare the cache as invalid is when its content is older than a certain timespan. A web browser could follow such a strategy when it determines whether it displays a page from its cache or reloads it from the web.
  • The source of data which is being cached has access to every cache and can actively invalidate them. Consider an in-process cache of an artifact doing database inserts and queries.

The cache I want to implement is going to support the first approach for now. Its only direct operation supported from a user’s perspective is getting the cached value. Internally it has to distinguish two different cases:

  1. The cache is valid: return the cached value
  2. The cache is invalid: cached value must be renewed and returned

The description of those two cases leaves open what the definiton of “when is the cache valid or invalid?” and “how can the cache be renewed?” is. Those definitions will depend on the actual usage scenario of the cache. Some developers might need a cache which becomes invalid after a certain time, others might need a cache which expires after it has been requested for a certain amount of times. Clearly the definition of when the cache is valid or invalid must be made flexible and exchangeable when implementing the cache class. In other words: It should be implemented as a policy. The same applies when obtaining fresh data in case the cache became invalid. Is calling a delegate provided by the user enough? Should that be done in a multi threading safe way? and so on. Eventually we identify two policies: An “invalidation policy” being responsible for the validity of the cache and a “retrieval policy” taking care of getting fresh data.

With that in mind we construct a basic workflow of the cache class:

  1. Inform invalidation policy that the cache is requested
  2. If invalidation policy claims that the cache is valid return the cached value
  3. Otherwise run retrieval policy to get update for the cached value
  4. Inform invalidation policy that the cache has been updated
  5. Return cached value

or in code:

this.cacheInvalidationPolicy.CacheRequested();
if (this.cacheInvalidationPolicy.IsCacheValid())
{
    return this.value;
}
this.value = this.cacheValueRetrievingPolicy.GetValue();
this.cacheInvalidationPolicy.CacheRenewed();
return this.value;

Looking at this workflow the retrieval policy turns out to be quite simple. It supports exactly one operation called “GetValue”:

public interface ICacheValueRetrievingPolicy<T>
{
    T GetValue();
}

Regarding the invalidation policy it needs to support the following operations:

  • Cache class informs the policy that the user requests the content of cache
  • Cache class wants to know whether the cache is valid
  • Cache class informs the policy that the cache has been renewed
public interface ICacheInvalidationPolicy

{
    void CacheRequested();
    bool IsCacheValid();
    void CacheRenewed();
}

Adding all things together – the cache class and the 2 policies – we are done with the first version of the value cache. I have created a small project on CodePlex called “Byleist” which contains the complete source code. You can find it here. Please note that Byleist is a portable library project. Thus you need to install the Portable Library Tools before opening the Byleist project.

Flattr this!

Policy-based class design in C#

A couple of years ago I read Andrei Alexandrescu’s book “Modern C++ Design” and was quite impressed with what he did there with C++ templates. His policy-based class design approach is an elegant and fascinating way of writing classes (respectively libraries) which can support every kind of user desired behavior by basically assembling classes out of little code snippets called “policies”. In his book he does that by specifying policies as type parameters and having a host class deriving from them (Please have a look at the wikipedia article here or his book for more details on that). Recently I have been thinking about policy-based design again and became interested in using this programming paradigma in C#.

Policies in C++ vs. Policies in C#

Let’s assume we want to create a class which can cache a value of type T and depending on a certain invalidation policy InvalidationPolicy the cache should no longer hand out the cached but ask for the latest value. In the original C++ policy-base design such a class might look like:

template<class T, template<class> class InvalidationPolicy>
class CacheOf : public InvalidationPolicy<T>
{
public:
    T GetValue()
    {
        if (!IsValid())
        {
            _value = GetLatestValue();
        }
        return _value;
    }
private:
    T _value;
};

As we can see the class CacheOf derives from its invalidation policy – a feature which is not available in C# as you cannot derive from generic type parameters. Unfortunately one of the key features in Alexandrescu’s approach is that the host class can be equipped with policies at compile time meaning that the desired behavior is baked into a brand new class (since the host is deriving from the policies) everytime a user specifies a new combination of policies.

Now imaging that the cache needs to be enhanced by a second policy which is responsible for retrieving the latest values. The CacheOf class needs to derive from this second policy as well – again a feature which is not available in C# as C# does not support multiple inheritance.

This first analysis is a bit disappointing because C# is missing two key features necessary which would be necessary to implement the original policy-based class design concept.

Strategy to the rescue

Not giving up so early, we have a look into the strategy pattern (as explained here) which has been described as the runtime relative of the policy-based design. Instead of generating new classes with every combination of policies, there is one compiled host class which takes 1 to n implementations of different strategies at runtime. By making them non exchangable once the host class is constructed we can come quite close to that aspect of  C++ version of policy based design.

public class CacheOf<T>
{
    private readonly IInvalidationPolicy _invalidationPolicy;

    private T _value;

    public CacheOf(IInvalidationPolicy invalidationPolicy)
    {
        _invalidationPolicy = invalidationPolicy;
    }

    public T GetValue()
    {
        if (!_invalidationPolicy.IsValid())
        {
            _value = GetLatestValue();
        }
        return _value;
    }
}

Maybe even better than the C++ method, we avoid code bloat (under the compiler hood) since whatever combination of the host and strategies is chosen no new class has to be baked and compiled.

Handy Generics?

While the C++ policy based class design relies on templates to substitute the policies, the strategy pattern based C# code above does not use generics. However, it is possible to use generics for creating the policies as well:

public class CacheOf<T, TInvalidationPolicy> 
    where TInvalidationPolicy : IInvalidationPolicy, new()
{
    private readonly IInvalidationPolicy _invalidationPolicy;

    public CacheOf()
    {
        _invalidationPolicy = new TInvalidationPolicy();
    }
}

Unfortunately this approach has one major disadvantage compared to the C++ version. In C++ it is possible to write:

template<typename int TExpirationTimeInSeconds>
class ConcretInvalidationPolicy
{
public:
    bool IsValid()
    {
        return TExpirationTimeInSeconds > _timeElapsed;
    }
private:
    int _timeElapsed;
};

And using like:

CacheOf<std::string, ConcretInvalidationPolicy<5> > cache;

(Please note that CacheOf has a different signature this time. That is because template parameter T is not of interest for the policy)

In C++ template parameters can be concret values instead of types. Something that is not at all supported in C#. For policies which require parameters for construction the way over C# generics and the new() constraint simply does not work. The conclusion is that you cannot use generics to specify the policies unless you want to follow a hybrid way where policies which do not require parameters are specified as generics and the rest is passed in as parameters for the constructor of the host class. An approach I personally don’t like as it becomes confusing and unclear to the user why some policies are specified as generics and others are not.

Accessing Policies

Obviously deriving from policies makes it possible to access policy functionality directly from the host class (assuming the right access modifiers and inheritance relationship). So for example changing a parameter a policy is working with is no problem in C++. However doing so requires the user to exactly know what assembled type he is working with. Something that might not be desirable especially when he wants to pass it around as other parties might not be interested in the concret policies used. Implementing policies as runtime strategies in C# does not stand back here.

Summary

Let’s summarize our observation for now:

  • Policy-based design is the hardwired strategy pattern design (at compile time in C++)
  • A C# class cannot derive from more than one base class (no multiple inheritance)
  • A C# class cannot derive from generic parameters
  • A C# generic cannot be a concret value in order to configure a policy
  • Implementing a policy-based designed class in C# must rely on strategies. At the latest when policies should be configurable
  • Accessing policies directly through the host class is not desirable. C# has no disadvantage here.

Recently so called mixins (wiki) for C# came into fashion. They enable C# programmers to have some sort of emulated multiple inheritance by cleverly using interfaces and extension methods. Even though being an exciting idea we will first evaluate the possibilites the strategy pattern offers and might have a look at mixins later.

Flattr this!