Closed averbraeck closed 1 year ago
Base idea (without generics):
interface Value extends Serializable, Cloneable
defines displayUnit, absolute, relative, toString, common functions for abs and relabstract class Scalar extends Number implements Value
defines the base methods of a Scalarabstract class IndexedValue implements Value
defines the methods for StorageType, mutable, immutable, isDense, isSparse, toDense, toSparseabstract class Vector extends IndexedValue implements Iterable
defines the base methods for a Vectorabstract class Matrix extends IndexedValue
defines the base methods for a Matrixinterface Relative
defines the methods that any relative value would have (as opposed to an absolute value)interface Absolute
defines the methods that any absolute value would have (as opposed to a relative value)interface RelWithAbs extends Relative
defines the additional methods of a relative value that belongs to an absolute valueFor the specific implementation for DoubleScalar
(as an example -- the design for Vector and Matrix and for Float is similar), we have 6 classes in the old situation: DoubleScalarInterface
, DoubleScalar
, AbstractDoubleScalar
, AbstractDoubleScalarRel
, AbstractDoubleScalarAbs
, and AbstractDoubleScalarRelWithAbs
. This will be reduced to one abstract classDoubleScalar
with three inner classes: Rel
, Abs
and RelWithAbs
each implementing one of the Relative
, Absolute
or RelWithAbs
interfaces.
Now with the generics (first design):
The Value
as the basis:
public interface Value<U extends Unit<U>, T extends Value<U, T>> extends Serializable, Cloneable
Every value has a unit, and has to be compatible with that unit.The Absolute
, Relative
and AbsWithRel
interfaces:
public interface Relative<U extends Unit<U>, R extends Relative<U, R>>
Specific functions for relatives (plus Relative, minus Relative, times constant, divide by constant).public interface RelWiithAbs<AU extends AbsoluteLinearUnit<AU, RU>, A extends Absolute<AU, A, RU, R>, RU extends Unit<RU>, R extends RelWithAbs<AU, A, RU, R>> extends Relative<RU, R>
The relative value R (e.g., Length) with unit RU has an attached absolute value A (e.g., Position) with unit AU. public interface Absolute<AU extends AbsoluteLinearUnit<AU, RU>, A extends Absolute<AU, A, RU, R>, RU extends Unit<RU>, R extends RelWithAbs<AU, A, RU, R>>
The absolute scalar A (e.g., Position) with unit AU has an attached relative scalar R (e.g., Length) with unit RU.The Scalar
for 0-dimensional Values:
public abstract class Scalar<U extends Unit<U>, S extends Scalar<U, S>> extends Number implements Value<U, S>, Comparable<S>
The scalar class defines its additional functions w.r.t. to Value
.The IndexedValue
for Vectors and Matrices:
public abstract class IndexedValue<U extends Unit<U>, S extends Scalar<U, S>, T extends IndexedValue<U, S, T, D>, D extends Storage<D>> implements Value<U, T>
The indexed value defines classes (T) of a higher dimension than Scalar that do have a corresponding Scalar (S) with a Unit (U). In addition, they store their data (D) using some kind of Storage. In a sense, the Data or Storage object is the multi-dimensional variant of the Number
of the Scalar.The Vector
for 1-dimensional Values:
public abstract class Vector<U extends Unit<U>, S extends Scalar<U, S>, T extends Vector<U, S, T, D>, D extends Storage<D>> extends IndexedValue<U, S, T, D> implements Iterator<S>
The vector class defines its additional functions w.r.t. to Value
.The Matrix
for 2-dimensional Values:
public abstract class Matrix<U extends Unit<U>, S extends Scalar<U, S>, T extends Vector<U, S, T, D>, D extends Storage<D>> extends IndexedValue<U, S, T, D>
The matrix interface defines its additional functions w.r.t. to Value
.Based on the above, DoubleScalar
would be defined as follows:
public abstract class DoubleScalar<U extends Unit<U>, S extends DoubleScalar<U, S>> extends Scalar<U, S>
This will define functions where the double
value such as double getSI()
extends what can be defined for a Scalar where the numeric definition of the quantity value is not yet specified.The DoubleScalar
classes for Abs, Rel and RelWithAbs can be implemented as follows:
public abstract class DoubleScalarRel<U extends Unit<U>, S extends DoubleScalar.Rel<U, S>> extends DoubleScalar<U, S> implements Relative<U, S>
public abstract class DoubleScalarRelWithAbs<AU extends AbsoluteLinearUnit<AU, RU>, A extends Scalar.Abs<AU, A, RU, R>, RU extends Unit<RU>, R extends DoubleScalar.RelWithAbs<AU, A, RU, R>> extends DoubleScalar<RU, R> implements AbsWithRel<AU, A, RU, R>
public abstract class DoubleScalarAbs<AU extends AbsoluteLinearUnit<AU, RU>, A extends Scalar.Abs<AU, A, RU, R>, RU extends Unit<RU>, R extends DoubleScalar.RelWithAbs<AU, A, RU, R>> extends DoubleScalar<AU, A> implements Absolute<AU, A, RU, R>
To stay consistent with the currently generated classes, the last three classes are called AbstractDoubleScalarRel
, AbstractDoubleScalarAbs
and AbstractDoubleScalarRelRelWithAbs
, which will be changed to the classnames without 'Abstract' later.
This implementation would simplify the number of interfaces and classes. A Speed
would implement/extend as follows:
Value --> Serializable, Cloneable
^
Scalar --> Number, Comparable
^
DoubleScalar
^
DoubleScalarRel --> Relative
^
Speed
A Length
would implement/extend as follows:
Value --> Serializable, Cloneable
^
Scalar --> Number, Comparable
^
DoubleScalar
^
DoubleScalarRelWithAbs --> RelWithAbs --> Relative
^
Speed
The current class structure for types of
Scalar
,Vector
andMatrix
is tremendously complex, especially given that the code for these classes is generated. To show the complexity for, e.g., aLength
:Length
extendsAbstractDoubleScalarRelWithAbs<PositionUnit, Position, LengthUnit, Length>
AbstractDoubleScalarRelWithAbs
extendsAbstractDoubleScalarRel
implementsDoubleScalarInterface.RelWithAbs
AbstractDoubleScalarRel
extendsAbstractDoubleScalar
implementsDoubleScalarInterface.Rel
AbstractDoubleScalar
extendsAbstractScalar
implementsDoubleScalarInterface
AbstractScalar
extendsNumber
implementsScalar
Scalar
extendsValue
,Comparable
Value
extendsValueFunctions
ValueFunctions
extendsSerializable
DoubleScalarInterface.RelWithAbs
extendsDoubleScalarInterface
,Scalar.RelWithAbs
DoubleScalarInterface
extendsScalar
Scalar.RelWithAbs
extendsScalar.Rel
Scalar.Rel
extendsScalar
,Relative
Relative
DoubleScalarInterface.Rel
extendsDoubleScalarInterface
,Scalar.Rel
In other words, 14 classes and interfaces define the contract and implementation of the
Length
scalar. And I left out the tremendously complex generics like:With the
default
option in interfaces, and the possibility to define static functions in interfaces, several abstract classes can be removed from the hierarchy, without changing anything in the contract of aScalar
,Vector
orMatrix
such as theLength
.