AbstractTypeFactoryPattern

The RosettaPattern for defining and instantiating CommonLisp types has proven to be very robust in handling basic and array types. But the demands of the DefstructType? and the evn more complex ClosClassType? have pushed us to extend the basic RosettaPattern to encompass the AbstractFactoryPattern? (Gamma et al). These complex types require the ability to replace the nested Factory class at runtime without sacrificing the in-situ type Java interface.

AbstractTypeFactoryPattern

RosettaPattern Factory Summary

The basic RosettaPattern defines a public interface with a nested public static factory class that constructs instances of the type. For example

public interface lisp.common.type.Integer {
  public static class Factory {
    public static lisp.common.type.Integer newInstance(int value) {
      ... code to create a Lisp Integer from the Java int ...
    }
  }
}
Once the interface is loaded, there is no mechanism (excluding the Java debugger) to alter the Factory class at runtime.

Core Abstract Pattern

Some complex CommonLisp types may be redefined at runtime in ways that are incompatible with the initial definition of the type. For example, a structure type - FOO - created by Defstruct can be completely altered (number, names, and types of slots) dynamically. Once that change is made, the constructor function, e.g. MAKE-FOO, will now produce instances of the new definition. Note that prior instances of FOO are still of type FOO, and the original accessor functions still work correctly with the older instances. The same will be true for a Java programmer. Both new and old instances are of the same Java type - for example - edu.cofc.cs.ServerArray.

The core pattern creates a level of indirection consistent with the constraints of the JVM. The pattern adds an additional nested static class of type AbstractFactory? . This class has no executable code but does possess a field that holds an instance of the appropriate factory type for the Lisp type. The type interface holds an instance of this AbstractFactory? . Since this is within an interface, it is a static final field (not changeable after class initialization).

The second component of the core pattern is the implementing class for the type. This class also possesses a static Factory class that produces instances of itself. The Factory class is of the same type as the AbstractFactory? defined in the type interface. To set this class as the current definition of the type just requires making an instance of the implementing class's Factory class and setting it in the field of the AbstractFactory? referenced in the type interface.

An example is in order...

Type Interface
public interface MyStruct  {
  public static final MyStruct.AbstractFactory factory = new MyStruct.AbstractFactory();

  public static class Factory {
    public static MyStruct newInstance(Object... args) {
      return factory.trueFactory.newInstance(args);
    }
  }
  
  public static class AbstractFactory {
    // DefstructFactory is a simple interface that simplifies and 
    // standardizes the Factory signature
    DefstructFactory trueFactory = null;
  }
}
Implementing Class
public class MyStructImpl implements MyStruct {
    public static final MyStructImpl.Factory trueFactory = new MyStructImpl.Factory();
    
    public static class Factory implements DefstructFactory {
        public Defstruct newInstance(Object... args) {
            return new MyStructImpl(args);
        }
    }
    ... implementing code goes here ...
}

DefstructType? Implementation

This section fills in some of the details pertinent to the Defstruct implementation. For convenience, common code across all Defstruct implementations are defined by a public interface Defstruct and an abstract class DefstructImpl.

Particular to Defstruct is the static code in the FooStructImpl class. This code is executed when the class is initialized. The static code automatically sets its Factory as the concrete Factory that will be used by the FooStruct interface. Greedy little things these DefstructImpls? ...

Type Interface
public interface FooStruct extends Defstruct {
  public static final FooStruct.AbstractFactory factory = new FooStruct.AbstractFactory();

  public static class Factory {
    public static FooStruct newInstance(Object... args) {
      return factory.trueFactory.newInstance(args);
    }
  }
  
  public static class AbstractFactory {
    // DefstructFactory is a simple interface that simplifies and 
    // standardizes the Factory signature
    DefstructFactory trueFactory = null;
  }
}
Implementing Class
public class FooStructImpl extends DefstructImpl implements FooStruct {
    public static final FooStructImpl.Factory trueFactory = new FooStructImpl.Factory();
    static { FooStruct.factory.trueFactory = trueFactory; }
    
    public static class Factory implements DefstructFactory {
        public Defstruct newInstance(Object... args) {
            return new FooStructImpl(args);
        }
    }
    ... implementing code goes here ...
}

Extending the FOO defstruct in Lisp is a bit tricky in the Java realm. For the complete architecture, see DefstructImplementation? . Here is just shown the type inheritence when creating a new structure BAR that extends FOO.

Subtype Interface
public interface BarStruct extends FooStruct {
    public static final BarStruct.AbstractFactory factory = new BarStruct.AbstractFactory();
    
    public static class Factory {
        public static Defstruct newInstance(Object... args) {
            return factory.trueFactory.newInstance(args);
        }
    }
    
    public static class AbstractFactory {
        DefstructFactory trueFactory = null;
    }
}
Implementing Class
public class BarStructImpl extends DefstructImpl implements BarStruct {
    public static final BarStructImpl.Factory trueFactory = new BarStructImpl.Factory();
    static { BarStruct.factory.trueFactory = trueFactory; }
    
    public static class Factory implements DefstructFactory {
        public Defstruct newInstance(Object... args) {
            return new BarStructImpl(args);
        }
    }
    ... implementing code goes here ...
}

Note that the type inheritence is defined by the interface inheritence, not implementing class inheritence. While BarStruct is a FooStruct, a BarStructImpl is not a FooStructImpl.

ClosClassType? Implementation

-- JerryBoetje - 01 Apr 2006

Topic revision: r4 - 2009-02-11 - 03:30:45 - MeganLusher
 
Home
This site is powered by the TWiki collaboration platformCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback