The Artima Developer Community
Sponsored Link

Heron-Centric: Ruminations of a Language Designer
Bolt-Ins for Contract and Extension Classes
by Christopher Diggins
April 27, 2005
Summary
At Matthew Wilson's behest, I have attempted to further explain my rationale behind separate extension classes, and contract verification classes. It turns out they fit very nicely in a design pattern which Matthew refers to as a bolt-in.

Advertisement

Bolt-Ins

A bolt-in is a sub-case of template parameter inheritance. Matthew Wilson defines a bolt-in (a term he attributes to his colleagues Leigh and Scott Perry) in his book Imperfect C++ as follows:
Bolt-ins are template classes with the following characteristics:

- Imperfect C++, page 375, by Matthew Wilson, published by Addison-Wesley, 2005

In all frankness I consider that to be a somewhat fluffy defintion, and I would have stated it more concisely as follows:
Bolt-ins are template classes which inherit from their primary parameterizing type, while accomodating its polymorphic nature.
The other parts of the definition are superflous, and do not add to the definition. They appear to be solely intended to distinguish bolt-ins from veneers. Matthew goes on to disintiguish a bolt-in primarily by its role:
... bolt-ins are concerned with significantly changing or completing the behavioural nature of (often partially defined) types. [...] The primary purpose of a bolt-in is to add or enhance functionality.

- Imperfect C++, page 375, by Matthew Wilson, published by Addison-Wesley, 2005

Unfortunately I find it difficult to identify specifically when I am using a bolt-in and when I am using plain old template parameter inheritance. However I will use the term bolt-in for the time being. I would however like to encourage Matthew to further refine the definitions of bolt-ins, veneers and attempt to formalize the other forms of template parameter inheritance patterns. On that note, Joel de Guzman suggested the term Parametric Base Class Pattern (PBCP) for all the forms of template parameter inheritance.

Separation of Concerns

The software engineering notion of "separation of concerns" refers to the fact that within a well-engineered piece of software, we should find code which is responsible for a specific concern located within a single module.

Following the principle of separation of concerns has the benefit of reduction of code coupling, and improvement of code cohesion. These are both well-known good software engineering practices. The advantages are that following these principles more naturally leads to more maintainable and reusable code.

Bolt-ins can be used to enforce separation of concerns, and to reduce code coupling.

Programming with Contracts

When it comes to the concern of verification of contractual conditions (i.e. preconditions, postconditions and invariants), this is commonly tangled with the implementation of the class itself. For instance consider the following class:
  class SimpleClass {
  public:
    Init() {
      // do initialization
    }
    void DoSomething() {
      // precondition: object must be initialized
      // do something
    }
  }
There is here an implied precondition to calling DoSomething() which is that the member function Init() must have been previously called on a particular instance. A common and somewhat naive approach to assuring the precondition is done by introducing a member variable:
  class SimpleClass {
  public:
    SimpleClass() : mbInit(false) {
    }
    Init() {
      // do initialization
      mbInit = true;
    }
    void DoSomething() {
      assert(mbInit);
      // do something
    }
  private:
    bool mbInit;
  }
Notice that mbInit is solely used for verifying that the class is used correctly. The problem is that it probably will only be needed during debug builds. The naive solution then would be:
  class SimpleClass {
  public:
    SimpleClass()
#ifdef _DEBUG
      : mbInit(false)
#endif
    { }
    Init() {
#ifdef _DEBUG
      // do initialization
      mbInit = true;
#endif
    }
    void DoSomething() {
      assert(mbInit);
      // do something
    }
  private:
#ifdef _DEBUG
    bool mbInit;
#endif
  }
Needlessly to say that is a mess. The problem results from a failure to separate concerns modularly. One improved solution is to use inheritance:
  class SimpleClass_with_contract : SimpleClass_impl {
  public:
    void SimpleClass_with_contract() : mbInit(false) {
    }
    void Init() {
      SimpleClass_impl::Init();
      mbInit = true;
    }
    void DoSomething() {
      assert(mbInit);
      SimpleClass_impl::DoSomething();
    }
  private:
    bool mbInit;
  };

  class SimpleClass_impl {
  public:
    void Init() {
      // do initialization
    }
    void DoSomething() {
      // do something
    }
  };

  #ifdef _DEBUG
    typedef SimpleClass_with_contract SimpleClass;
  #else
    typedef SimpleClass_impl SimpleClass;
  #endif
This solution is good, but the contract verification class is not reusable because it is coupled with that particular implementation. This arises because we have only partially separated the concern of contract verification. Ideally I want something reusable, so I will use a class which inherits from its template parameters (a bolt-in).
  template<typename Impl_T>
  class Simple_contract : Impl_T {
  public:
    void Simple_contract() : mbInit(false) {
    }
    void Init() {
      Impl_T::Init();
      mbInit = true;
    }
    void DoSomething() {
      assert(mbInit);
      Impl_T::DoSomething();
    }
  private:
    bool mbInit;
  };

  class SimpleClass_impl {
  public:
    void Init() {
      // do initialization
    }
    void DoSomething() {
      // do something
    }
  };

  #ifdef _DEBUG
    struct SimpleClass :
      Simple_contract<SimpleClass>
    { };
  #else
    struct SimpleClass :
      SimpleClass_impl
    { };
  #endif
This new contract verification class can now be used with other classes with similar interfaces:
  class AnotherSimpleClass_impl {
  public:
    void Init() {
      // do initialization
    }
    void DoSomething() {
      // do something
    }
  };

  #ifdef _DEBUG
    struct AnotherSimpleClass :
      Simple_contract<AnotherSimpleClass>
    { };
  #else
    typedef AnotherSimpleClass_impl AnotherSimpleClass;
  #endif
This demonstrates how through the diligent practice of separation of concerns we can arrive at code which is more reusable.

Extension Classes

The public member functions of many classes can be divided up into two relatively distinct groups, core functions and derived functions. The derived functions can be thought of as syntactic sugar, that is functions which can be defined in terms of the core functions. These derived functions are a good candidate to use within a bolt-in. Consider the case of the following naive and minimalist string implementation:
  class MyString_impl {
  public:
    void SetCount(int n) {
      m.resize(n);
    }
    void SetChar(int n, char c) {
      m[n] = c;
    }
    char GetChar(int n) const {
      return m[n];
    }
    int Count() {
      return m.size();
    }
  private:
    std::vector<char> m;
  };
This class is too minimalist to be of much use as-is, however with this basic implementation you can implement virtually every other concievable string member function. By writing the derived functions within a bolt-in, I can reuse the derived set of memember functions on any class which matches the code interface. For instance consider the following bolt-in:
  template<typename Impl_T>
  class String_ext : public Impl_T {
  public:
    void Concat(const Impl_T& x) {
      int n = Count();
      SetCount(n + x.Count());
      for (int i=n; < Count(); i++) {
        SetChar(i, x.GetChar(i-n));
      }
    }
    void Assign(const Impl_T& x) {
      SetCount(x.Count());
      for (int i=0; i < Count(); i++) {
        SetChar(i, x.GetChar());
      }
    }
    Impl_T SubString(int n, int cnt) const {
      Impl_T s;
      s.SetCount(cnt);
      for (int i=0; i < cnt; i++) {
        s.SetChar(i, GetChar(i + n));
      }
      return s;
    }
    // and so on and so forth
  };
This extension class can be bolted on to any compatible class implementation as simply as:
  typedef String_ext<MyString_impl> MyString;
The advantage of doing this is that the extension class can be reused on any class matching the core interface. This also reduces the coupling between extension functions and the implementation to a set of four functions. Refactoring and debugging the code as a result becomes much easier.

We can also define a contract verification class for MyString as follows:

  template<typename Impl_T>
  class String_contract : public Impl_T {
  public:
    void SetChar(int n, char c) {
      assert(n < Count());
      Impl_T::SetChar(n);
      assert(GetChar(n) == c);
    }
    char GetChar(int n) const {
      assert(n < Count());
      return Impl_T::GetChar(n);
    }
  }
Tying everything together gives us:
  #ifdef _DEBUG
    typedef String_ext<String_contract<MyString_impl> > MyString;
  #else
    typedef String_ext<MyString_impl> MyString;
  #endif

The Big Gotcha

Hopefully I have demonstrated the theoretical advantages of separating classes into reusable components as bolt-ins. There is however a big problem with all of this, constructor inheritance. In C++ constructors are not inherited, which really puts a wrench in the gears (and makes me wish I was working with Heron instead of C++).

One solution I am aware of is to use template constructors. This is not a perfect solution though.

My currently preferred solution to this design conundrum is to forego initializing construction entirely within my libraries. A rather drastic and contentious measure, but perhaps one which may pay off, because it opens the door more widely to sophisticated usage of template parameter inheritance techniques such as bolt-ins, contract verificiation classes, extensions classes, and more. Some debate on the merits of this approach can be found in the comments of my earlier blog entry Two Stage Construction in C++ versus Initializing Constructors

Talk Back!

Have an opinion? Readers have already posted 16 comments about this weblog entry. Why not add yours?

RSS Feed

If you'd like to be notified whenever Christopher Diggins adds a new entry to his weblog, subscribe to his RSS feed.

About the Blogger

Christopher Diggins is a software developer and freelance writer. Christopher loves programming, but is eternally frustrated by the shortcomings of modern programming languages. As would any reasonable person in his shoes, he decided to quit his day job to write his own ( www.heron-language.com ). Christopher is the co-author of the C++ Cookbook from O'Reilly. Christopher can be reached through his home page at www.cdiggins.com.

This weblog entry is Copyright © 2005 Christopher Diggins. All rights reserved.

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use