Support pattern

The purpose of the support pattern is to implement a number of target classes all supporting a common interface target, using a targetSupport class to implement common functionality. The pattern is a more explicit version of some common less structured inheritance patterns.

Even though the purpose of the pattern it so create many target classes, the pattern is described for one of these target classes. In that context there are two actors:


 * Target
 * The targets are the class we want to implement.


 * Support
 * The targetSupport is a class that implement those parts of the target that is to be reused/shared for other target's.

There are three contracts in the pattern:


 * The target interface, which defines the target's public interface.
 * The targetSupport</vp> interface, which defines the target</vp>'s view of the targetSupport</vp>.
 * The targetSupportSite</vp> interface, which defines the targetSupport</vp>'s view of the target</vp>.

PFC has many of uses the support pattern.

The contents of the target interface solely depend on overall problem, and does not contain anything that have to do with the design patters. For the the description we have added a property and a predicate:

interface target

properties targetProperty : string.

predicates targetPredicate :.

end interface target

Likewise the class declaration of the target (here target_1</vp>) solely depends on the overall problem:

class target_1 : target ... end interface target_1

It will either construct objects of the target</vp> type (as above), or of a type that supports target</vp> as here:

interface target_2 supports target % additional special target_2 functionality end interface target_2

class target_2 : target_2 ... end interface target_2

The targetSupport</vp> and target</vp> classes are in symbiosis with one and other:


 * The targetSupportSite</vp> interface contains entities that the targetSupport</vp> class will need from the target</vp>.
 * And the targetSupport</vp> interface contains entities that the targetSupport</vp> class provides to the <vp>target</vp>.

The exact contents of these interfaces will depend on how the <vp>targetSupport</vp> class is supposed to support the construction of the <vp>target</vp> classes. For the the description we have added a predicate predicate to the targetSupportSite:

interface targetSupportSite predicates sitePredicate :. end interface targetSupportSite

For the description we will assume that the targetSupport class will directly implement the <vp>targetProperty</vp> and provide a support predicate, <vp>supportPredicate</vp>, which the target class can use to implement the <vp>targetPredicate</vp>.

Since <vp>targetProperty</vp> is to be exposed directly as <vp>target::targetProperty</vp> it must be declared as coming from the <vp>target</vp> interface:

interface targetSupport properties from target targetProperty

predicates supportPredicate :. end interface targetSupport

<vp>targetSupport</vp>'c constructor will (at least) take a <vp>targetSupportSite</vp> as parameter, here we have also chosen that it should have an initial value for the <vp>targetProperty</vp>:

class targetSupport : targetSupport constructors new : (targetSupportSite Site, string TargetPropertyInit). end class targetSupport

The implementation of the <vp>targetSupport</vp> class will store the site in a fact so that the site can be accessed where required. This code also contains example implementation of the <vp>targetSupport</vp> interface

implement targetSupport

facts site : targetSupportSite. targetProperty : string.

clauses new(Site, TargetPropertyInit) :- site := Site, targetProperty := TargetPropertyInit.

clauses supportPredicate(...) :- ...       site:sitePredicate,  % site functionality can be used where required ... end implement targetSupport

The implementation of the target classes (here <vp>target_1</vp>) we will inherit from <vp>targetSupport</vp> to get access to the shared functionality, it will also have to support and implement the <vp>targetSupportSite</vp> interface and privide itself (i.e. <vp>This</vp>) as site:

implement target_1 inherits targetSupport % access to shared functionality by inheritance supports targetSupportSite % support the site so that the targetSupport can access functionality here

clauses new(...) :- targetSupport::new(This, "target_1_property"). % initialization of the base class

% The targetProperty is directly inherited from the targetSupport % but this class will have to implement targetPredicate clauses targetPredicate :- ...       supportPredicate,  % we can use the inherited supportPredicate in the target class ...

clauses sitePredicate :- % The target class must implement the sitePredicate ... end implement target_1

The support pattern very explicitly express what functionality the support class provides to the target classes and vice versa.