'. '

ClearDefinitionOfVersion

From APIDesign

(Difference between revisions)
Jump to: navigation, search
(New page: Sometimes API designers need to specify a set of methods that others have to implement. Yet the designers know that the set is going to be valid for just a limited amount of releases. ...)
Line 1: Line 1:
Sometimes [[API]] designers need to specify a set of methods that others have to implement. Yet the designers know that the set is going to be valid for just a limited amount of releases. It is clear that in some future release, the set of methods will have to change.
Sometimes [[API]] designers need to specify a set of methods that others have to implement. Yet the designers know that the set is going to be valid for just a limited amount of releases. It is clear that in some future release, the set of methods will have to change.
-
This commonly happens when one needs a to capture a language. For example for describing capabilities of [[Java]], one would have ''1.0'' version, then ''1.1'' version of the interface would add support for inner classes. ''1.4'' version would add ''assert'' keyword. Version ''1.5'' would have support for generics and other features, etc.
+
This commonly happens when one needs a to capture a state of a programming language. For example for describing capabilities of [[Java]], one would have ''1.0'' version. Later ''1.1'' version of the [[API]] would add support for inner classes. Few years after that ''1.4'' version would add '''assert''' keyword. Subsequent version ''1.5'' would have support for generics and other features, etc.
-
As an example, imagine that one needs to define a visitor for language that supports ''numbers'' and ''plus'' operation. One can do it with interface ''Visitor10'':
+
As an example, imagine that one needs to define a [[visitor]] for language that supports ''numbers'' and ''plus'' operation. One can do it with interface ''Visitor10'':
<source lang="java" snippet="visitor.cleandefinitionofversion"/>
<source lang="java" snippet="visitor.cleandefinitionofversion"/>
-
Later, when the language is extended to also support ''Minus'' operation one defines a new interface for this ''language v2.0'':
+
Later, when the language is extended to also support ''Minus'' operation one defines a new, extended interface for this ''language v2.0'':
<source lang="java" snippet="visitor.cleanversion.v2"/>
<source lang="java" snippet="visitor.cleanversion.v2"/>
-
And later, in another version, one can even define new interface that replaces integer ''Number''s with ''Real'' ones:
+
The interface in fact does not need to extend each other. For example it is possible to create another version that defines new interface that replaces methods dealing with integer ''Number''s with ''Real'' ones:
<source lang="java" snippet="visitor.nonmonotonic.visitor"/>
<source lang="java" snippet="visitor.nonmonotonic.visitor"/>
-
By using separate interfaces for each version, one clearly communicates to the [[API]] users willing to work with (for example) version 2.0 what set of methods must be implemented.
+
By using separate interfaces for each version, one [[Clarity|clearly communicates]] to the [[API]] users willing to work with (for example) version 2.0 what set of methods must be implemented.
-
This is one of the examples where usage of [[Java]] interface (and not classes) is more than appropriate.
+
This is one of the patterns where usage of [[Java]] interfaces (and not classes) is more than appropriate.
[[Category:APIDesignPatterns:Clarity]]
[[Category:APIDesignPatterns:Clarity]]
[[Category:APIDesignPatterns:Evolution]]
[[Category:APIDesignPatterns:Evolution]]

Revision as of 19:30, 24 April 2009

Sometimes API designers need to specify a set of methods that others have to implement. Yet the designers know that the set is going to be valid for just a limited amount of releases. It is clear that in some future release, the set of methods will have to change.

This commonly happens when one needs a to capture a state of a programming language. For example for describing capabilities of Java, one would have 1.0 version. Later 1.1 version of the API would add support for inner classes. Few years after that 1.4 version would add assert keyword. Subsequent version 1.5 would have support for generics and other features, etc.

As an example, imagine that one needs to define a visitor for language that supports numbers and plus operation. One can do it with interface Visitor10:

Code from Language.java:
See the whole file.

public final class Language {
    private Language() { }
 
    public static abstract class Expression {
        Expression() {}
        public abstract void visit(Visitor v);
    }
    public static final class Plus extends Expression {
        private final Expression first;
        private final Expression second;
 
        public Plus(Expression first, Expression second) {
            this.first = first;
            this.second = second;
        }
        public Expression getFirst() { return first; }
        public Expression getSecond() { return second; }
        @Override
        public void visit(Visitor v) { 
            if (v instanceof Visitor10) {
                ((Visitor10)v).visitPlus(this);
            } else {
                v.visitUnknown(this);
            }
        }
    }
    public static final class Number extends Expression {
        private final int value;
        public Number(int value) { this.value = value; }
        public int getValue() { return value; }
        @Override
        public void visit(Visitor v) { 
            if (v instanceof Visitor10) {
                ((Visitor10)v).visitNumber(this);
            } else {
                v.visitUnknown(this);
            }
        }
    }
 
    public interface Visitor {
        public void visitUnknown(Expression e);
    }
 
    public interface Visitor10 extends Visitor {
        public void visitPlus(Plus s);
        public void visitNumber(Number n);
    }
}
 

Later, when the language is extended to also support Minus operation one defines a new, extended interface for this language v2.0:

Code from Language.java:
See the whole file.

public interface Visitor {
    public void visitUnknown(Expression e);
}
public interface Visitor10 extends Visitor {
    public void visitPlus(Plus s);
    public void visitNumber(Number n);
}
/** @since 2.0 */
public interface Visitor20 extends Visitor10 {
    public void visitMinus(Minus s);
}
 

The interface in fact does not need to extend each other. For example it is possible to create another version that defines new interface that replaces methods dealing with integer Numbers with Real ones:

Code from Language.java:
See the whole file.

/** @since 3.0 */
public interface Visitor30 extends Visitor {
    public void visitPlus(Plus s);
    public void visitMinus(Minus s);
    public void visitReal(Real r);
}
 

By using separate interfaces for each version, one clearly communicates to the API users willing to work with (for example) version 2.0 what set of methods must be implemented.

This is one of the patterns where usage of Java interfaces (and not classes) is more than appropriate.

Personal tools
buy