You are currently browsing the archives for the pattern tag.

Adapter pattern memory models

June 8th, 2012

Following on from the article on Adapter patterns (Read more here) I’ve decided to explore the memory models of each of these patterns.

We’ll start with the simple case of a UtilityProvider class being a simple class with no virtual methods. Then we’ll look at what happens when the UtilityProvider has virtual functions added.

To flesh out the memory models I’ve added (arbitrary) data to both the UtilityProvider class and its adapters.

These memory models are based on the IAR Embedded Workbench C++ compiler. It’s a fairly typical compiler for embedded systems development. For simplicity I’m ignoring padding issues; compilers will usually pad to the next word boundary, so assume what you see is word-aligned objects.

The Object Adapter

A quick reminder of the Object Adapter pattern. The ObjectAdapter class realises the IService interface and forwards on all calls to the encapsulated UtilityProvider object. The Utility provider object can be created by the client and passed in the adapter, allocated on the free store by the adapter, or stored as a nested (composite) object.

clip_image002

Figure 1 – The Object Adapter pattern

Object Adapter memory model

If the UtilityProvider is created outside the adapter (or on the free store) the memory model is as shown in Figure 2. Note the ObjectAdapter class has a vtable pointer since it implements the IService interface. The de-facto model is to place the vtable pointer as the first element in the class (in other words at ‘this’)

clip_image004

Figure 2 – ObjectAdapter with a reference to the UtilityProvider object

If the UtilityProvider object is a composite object the memory model changes (Figure 3). Note, the ObjectAdapter vtable pointer is still the first element in the object.

clip_image006

Figure 3 – ObjectAdapter with nested UtilityProvider

The Class Adapter pattern

A Class Adapter realises the client-required interface but privately inherits from the UtilityProivder class (hiding its methods) – See Figure 4

clip_image008

Figure 4 – The Class Adapter pattern

Class Adapter memory model

The memory model for inheritance in C++ constructs a base class object as part of the derived class, so we should expect a memory model similar to that of the composite-object Object Adapter. In fact, it is identical( Figure 5)

clip_image010

Figure 5 – Class Adapter

Adding virtual functions to the UtilityProvider.

Suppose our UtilityProvider class has virtual functions (for example Figure 6). How does this affect the memory model?

/////////////////////////////////////////////////////////////////////
//

class UtilityProvider
{
public:
  UtilityProvider();
  void func1();
  void func2();
  void func3();
  void func4();
  virtual void func5(); // Requires a vtable.

protected:
  void helperFunction();

private:
  // Private data.
};

Figure 6 – UtilityProvider with virtual functions

The Object Adapter memory model

When the UtilityProvider class has virtual functions it gets its own vtable and vtable pointer (Figure 7). It’s worth noting the order in which the memory is allocated depends on the order of declaration in the class definition. In this example I’ve put the UtilityProvider object as the first declaration; before any other data.

Note also that the ObjectAdapter’s vtable pointer is still the first element in the object.

clip_image012

Figure 7 – Object Adapter with virtual UtilityProvider

Class Adapter memory model

In a single-inheritance model the derived class shares its vtable pointer with the base class (that’s the basis of polymorphism. In the case of the Class Adapter model this isn’t the case. Both the ClassAdapter and UtilityProvider retain their own vtable pointers. (This allows the ClassAdapter to have a virtual function with the same signature as the UtilityProvider, and still call the UtilityProvider’s virtual function. If they shared the same vtable pointer you could end up with an infinite recursive call)

There is also a difference on memory layout depending on whether the IService interface is the Primary Base Class and the UtilityProvider is a Secondary Base Class( Figure 9); or vice versa (Figure 10)

You should always favour having the Interface as the Primary Base Class. For more information on why see this white paper.

/////////////////////////////////////////////////////////////////////
//
class ClassAdapter : public IService, // Primary Base Class
                     private UtilityProvider // Secondary Base Class
{
  // ....
};

/////////////////////////////////////////////////////////////////////
//
class ClassAdapter : private UtilityProvider, // Primary Base Class
                     public IService // Secondary Base Class
{
  // ....
};

Figure 8 – ClassAdapter definitions with different PBC and SBC

clip_image014

Figure 9 – ClassAdapter with IService as Primary Base Class

clip_image016

Figure 10 – ClassAdapter with UtilityProvider as Primary Base Class

Summary

The memory models of the Adapter patter are all very similar. Remember when programming these patterns the associated overheads:

  • Extra code space for the vtable(s)
  • An extra vtable pointer for each object with virtual functions
  • The overhead of virtual function calls (note the double overhead if you are calling a virtual function on the original class!)

Interface adaption, and private inheritance

May 22nd, 2012

A problem with code re-use

It’s a common situation in software development: you’ve acquired a class – either from a third-party source, or inherited from another project – that’s got some really useful features, but its interface doesn’t quite meet your immediate needs. Two typical scenarios are:

  • The interface is too big; you just want your clients to have a small subset of the facilities on offer.
  • The interface signatures don’t match what your client code needs (and you don’t want to – or can’t – change the client code.

 

clip_image002

Figure 1 – A mis-match between the interface the client requires and the interface provided by the utility class

The solution is to use the Adapter pattern – encapsulate the useful class within an object of your own devising and present a new interface for your client. There are two approaches to creating adapters – wrapping an object (known as the Object Adapter pattern) and the (less-well-known) Class Adapter pattern, which uses private inheritance (for more details on these patterns see Design Patterns. Elements of Reusable Object-Oriented Software, p139).

The Object Adapter pattern

In the Object Adapter pattern the Adapter class implements the service interface as required by the client but contains a nested object that implements the actual behaviour (see Figure 2)

clip_image004

Figure 2 – The Object Adapter pattern

/////////////////////////////////////////////////////////////////////
//
class IService
{
public:
  virtual void service1() = 0;
  virtual void service2() = 0;
  virtual void service3() = 0;
  virtual void service4() = 0;
};

/////////////////////////////////////////////////////////////////////
//
class UtilityProvider
{
public:
  void func1();
  void func2();
  void func3();
  void func4();

protected:
  void helperFunction();
};

 

The ObjectAdapter class realises the IService interface, and encapsulates a UtilityProvider object. There are three ways the UtilityProvider object can be bound to the ObjectAdapter:

  • The UtilityProvider object can be created by the client then passed in to the constructor of the ObjectAdapter. This is how the pattern is implemented in Design Patterns; and how it is done in this example.
  • The UtilityProvider can be created as a composite, nested object.
  • The UtilityProvider object can be allocated from the free store in the ObjectAdapter’s constructor and de-allocated in the ObjectAdapter’s destructor.

All three options are viable; but be careful with the second two if the ObjectAdapter instance is going to be copied (you will need to ensure the UtilityProvider object is properly copied)

/////////////////////////////////////////////////////////////////////
//
class ObjectAdapter : public IService
{
public:
  ObjectAdapter(UtilityProvider& obj) : utilityObject(obj) {}

private:
  virtual void service1()   // Simple pass-through call... 
  {
    utilityObject.func1();
  }

  virtual void service2()   // Combining behaviours...
  {
    utilityObject.func1();
    utilityObject.func2();
  } 

  virtual void service3()
  {
    // ... 
  }

  virtual void service4()
  {
    utilityObject.helperFunction();  // ERROR - protected member 
  }

  UtilityProvider& utilityObject;
};

/////////////////////////////////////////////////////////////////////
//
int main()
{
  UtilityProvider provider;
  IService& client = *(new ObjectAdapter(provider));

  client.service1();
  client.utilityObject.func1();  // ERROR – private object.

  // ...

  delete &client;
}

 

Note our client depends only the interface; not on any particular implementation. We can substitute our ObjectAdapter class since it inherits from the IService class.

Our new methods can be used to change the names (or signatures) of the UtilityProvider class’s methods. We can even combine Useful methods behind a more abstract interface.

Note, however, we cannot get access to any protected members of UtilityProvider.

Our client code can access our methods, but cannot get access to any of the methods of the (privately) nested UtilityProvider object.

Using private inheritance – the Class Adapter

The Class Adapter pattern uses private inheritance to encapsulate the UtilityProvider’s behaviour and present a new interface.

clip_image006

Figure 3 – The ClassAdapter inherits from both the Interface and the Implementation

Normally when we do inheritance in C++ we use public inheritance. Public inheritance does not change the access modifiers from the base class to the derived class. So public members in the base remain public in the derived; protected members remain protected; and private members remain private.

With private inheritance, any public or protected members in the base class become private in the derived class; and therefore become unavailable to clients of the derived class.

We make use of the change of access modifiers in the Class Adapter pattern. The ClassAdapter publically inherits from the IService interface (so the client can call its methods) but privately from the UtilityProvider (thus hiding all those methods)

/////////////////////////////////////////////////////////////////////
//
class ClassAdapter : public  IService,       // Interface
                     private UtilityProvider // Implementation
{
private:
  virtual void service1()
  {
    UtilityProvider::func1();
  }

  virtual void service2()
  {
    UtilityProvider::func1();
    UtilityProvider::func2();
  }

  virtual void service3()
  {
    // ... 
  }
  virtual void service4()
  {
    UtilityProvider::helperFunction();  // OK – Can access protected
  }
};

/////////////////////////////////////////////////////////////////////
//
int main()
{
  IService& client = *(new ClassAdapter);

  client.service1();

  // ...

  delete &client;
}

 

As before, we can add new methods to the Adapter class public interface. These methods then call on the base class operations. Again, we can combine methods to present a more abstract interface.

In addition, now we can access the protected members of the Useful class.

Simplifying an interface – the Adapting Façade

Often your client isn’t dependent on an interface, but you still might want to modify the interface of your utility class. Typically you’ll want to change a few methods and/or provide a subset of the original class’s interface.

Strictly, this isn’t the Adapter pattern. It’s actually a variation of the Façade pattern (Design Patterns. Elements of Reusable Object-Oriented Software, p187). The Façade pattern is designed to simplify access multiple subsystems, or non-OO APIs with a single, unified interface. In this case we only have one subsystem, our utility class. Let’s call it an Adapting Façade (for want of a better term).

/////////////////////////////////////////////////////////////////////
//
class AdaptingFacade : private UtilityProvider
{
public:
  void abstractMethod()
  {
    UtilityProvider::func1();
    UtilityProvider::func2();
  }

  // 'Expose' private methods from
  // Base class.
  //
  using UtilityProvider::func3;
};

/////////////////////////////////////////////////////////////////////
//
int main()
{
  AdaptingFacade adaptingFacade;

  adaptingFacade.abstractMethod();
  adaptingFacade.func1();            // ERROR cannot access private member
  adaptingFacade.func3();            // OK - exposed via 'using'
}

 

As with the Class Adapter pattern we use private inheritance to hide the utility class’s interface and present our own. Again, we can access protected members of the utility class. We can also make use of the using keyword to ‘expose’ private members of the Useful class into the Adapter Facade’s public interface. The method func3(), which was private (because of the private inheritance), has now been made public. This neat facility allows us to present a subset of the original class’s interface without the overhead of a pass-through call.

In summary

Both the Object Adapter pattern and Class Adapter patterns are valid ways of modifying an existing class’s interface to work better in a new environment. The Class Adapter pattern adds the benefit that you can access any protected members of the original class.

The Adapting Façade allows us to modify a class’s interface and also produce a reduced subset of the originals.

In the next article we’ll have a look at memory usage with the adapter patterns.

Baselines and Branching

June 6th, 2011

A baseline is an identified set of files and directories in which there is one and only one version of each file and directory.

A baseline identifies one particular configuration of the software (or a subset thereof)

The baseline represents a fixed point in the development; that may be recreated as required.

Specifying a Baseline

A baseline defines a set of files, each at a particular version. These need not be the latest (most recent) version. A baseline label uniquely identifies the configuration. Files may belong to one or more baselines.

image

Figure 12 – A baseline defines a set of files, each at a particular version.

 

In the example of Figure 12 baseline BL1.0 is the first baseline recorded. It consists of seven artefacts, each at a unique revision number. For this example, assume that BL1 records the most recent versions of each artefact. As development progresses each artefact is modified as required (that is, some artefact are modified, some are not). At some time later another baseline is taken – BL2.0. In this case BL2.0 records the current latest revisions of each file. Notice that artefact F is unchanged, so F v1.0 is included in both baseline BL1.0 and BL2.0.

In general each successive baseline contains more recent versions of files (but not always).

When to use baselines

Baselines are a key tool in managing and auditing the state of a project. Baselines should be created prior to any significant project activity:

Development

Baselines provide a ‘working’ point in the project’s configuration. Recording a baseline prior to making a major change to the system allows the development to start from a known working point and, in the event of something going wrong, to ‘roll-back’ to that working configuration.

Baselines should be made prior to starting any new package of work (as evidence of project progress); and new feature development; prior to changing or upgrading any tools; etc.

Release

A baseline records the complete configuration of the product that is being distributed from the development department (whether that is an external customer or just the test department).

Audit

Baselines provide process evidence for audits and also time-stamped evidence of the project’s progress (for example, starting a particular work package)

 

Baseline of baselines

In larger, more complex systems, we may choose to manage the system complexity using a ‘Components’ approach. Each ‘component’ represents some aspect of system functionality – for example a subsystem. Using this approach each component of the system has its own (unique) baselines, independent of any other component (Figure 13).

image

Figure 13 – each component of the system has its own unique set of baselines

Note, not shown in this example is the fact that components may share artefacts. For example, both component A and component B may share a common artefact H; with each component using a different revision.

image

Figure 14 – A complete system constructed from a  ‘baseline of baselines’

The (complete) product’s baselines are constructed from (unique) combinations of the component’s baselines (Figure 14). This method is known as a ‘Baseline of baselines.’

 

Branch Patterns

Branching is the (apparent) duplication of an artefact, or set of artefacts, so that they can be developed independently of the main development activity. Branching is a facility of all revision control systems. RCS systems incorporate mechanisms (such as lazy copying) to avoid the potentially massive overhead of copying artefacts between branches. Branches allow parallel development, which is essential in all but the most simple of software developments.

Conceptually, the artefacts that make up a product or system form the main branch or trunk of the development. The trunk represents the main line of development for the product. Ideally, the trunk represents the most recent (working) configuration of the project. Branches represent alternative paths of development. Motivations for branching include:

  • Maintenance of released products
  • Customer specific additions or modifications
  • New development work
  • Research and development projects

Note, with branching the unique identifier of an artefact must be extended to include the artefact’s branch. Thus artefact MyDoc v1.1 will be extended to be (something like) \main\MyDoc v1.0, which will be different to \main\branch1\MyDoc v1.0. In this case \main identifies the trunk branch and \main\branch1 identifies the first branch from the trunk branch.

Uncontrolled branching can lead to major administrative issues (many companies have a RCS administrator simply to keep the repository ‘healthy’)

The branching patterns presented below are a systematic approach to version tree usage. They are design to reduce the complexity of repository branch management and allow effective project management.

 

Sequential

The Sequential branching pattern (Figure 15) is the simplest model – in that it contains no branching! In essence, it is a ‘pseudo-branching’ pattern.

All development is performed on the trunk branch. All development is linear; no parallel development can be supported. This pattern requires, and enforces mutually exclusive changes to artefacts. By default, this is the pattern followed by all artefacts.

 

image

Figure 15 – The ‘pseudo-branching’ pattern, Sequential.  There is no branching!

The Sequential pattern is fine for projects where there is no parallel development required and the current release always has the most up-to-date developments. In general, this restricts the pattern’s use to simpler projects.

 

Off-Shoot

The Off-Shoot branching pattern allows a legacy version (the mainline development) to have derivative and independent versions created.

 

image

Figure 16 – The off-shoot branching pattern

The off-shoot branch can be created retrospectively – that is, development on the trunk branch could be well advanced before the off-shoot branch is created. The off-shoot is never merged into another branch. Off-shoots may also have their own off-shoots.

Note that the main trunk is baselined before the offshoot is created.

 

Loop

The Loop branch pattern is a variation on the Off-Shoot pattern. The Loop pattern allows basic managed development.

 

image

Figure 17 – The Loop branching pattern

In this example the trunk branch represents the release branch. That is, all releases are from the main branch. New development is performed in an Off-Shoot branch (called \Dev BL 2.0 in the example since it represents the new code that will appear in baseline 2.0 of the product). The new development work is independent of any release code.

Once development has been completed in the Off-Shoot branch the Loop is closed by merging the off-shoot back into its parent branch. Note that baselines in the main branch only represent completed development activities.

 

Integration

The Integration pattern extends the Loop pattern model to allow managed and concurrent development.

 

image

Figure 18 – the Integration branching pattern

As above, the main trunk branch represents the release branch for the code; no development is performed on the main branch.

For a new feature a new branch is created (\Integration). The new development consists of three work packages. In this example Work Package 1 (\WBS1) must be completed before Work Package 3 (\WBS3) can be started.

Within the \Integration branch two new Loops are started (\WBS1and \WBS2). The work on both packages continues independently and in parallel. When Work Package 1 is complete it is merged into the \Integration branch. At this point Work Package 3 can be started, so a new branch is created from the \Integration branch (after baselining the \Integration branch – not shown). Some time later Work Package 2 is completed and merged into the \Integration branch. Finally Work Package 3 is complete and merged. To complete development the \Integration branch is merged back into the mainline development.

The Integration pattern builds on the smaller patterns to form a comprehensive branch/merge strategy. The strength of this pattern is the RCS archive reflects the development project plan.

%d bloggers like this: