我正在开发一个符合我需求的线性代数库。目前我有2个想法,但我想知道这两个结构的优点和缺点是做出好的选择。
例如使用向量:
//First structure (simple inheritance using generics
//to prevent instanceof and casting in subclasses
public abstract class AbstractVector<T>{
public abstract T method(T t){...}
...
}
public class Vector2 extends AbstractVector<Vector2>{
public Vector2(){...}
//Implements AbstractVector method, generic T is Vector2
public Vector2 method(Vector2 vector){...}
}
public class Vector3 extends AbstractVector<Vector3>{...}
public class Vector4 extends AbstractVector<Vector4>{...}
//Second structure (using the structure of java AbstractList/List/ArrayList
//prevents instanceof and casting in subclasses )
public interface Vector<T>{
T method(T t){...}
}
public abstract class AbstractVector<T> implements Vector<T>{...}
public class Vector2 extends AbstractVector<Vector2>{
public Vector2(){...}
//Implements Vector interface method, generic T is Vector2
public Vector2 method(Vector2 vector){...}
}
public class Vector3 extends AbstractVector<Vector3>{...}
public class Vector4 extends AbstractVector<Vector4>{...}
在使用方面:
//1st structure
Vector2 vector2 = new Vector2();
Vector3 vector3 = new Vector3();
vector2.method(vector3) //Compile time error!
//2nd structure (I use Vector type main advantage of interface)
Vector vector2 = new Vector2();
Vector vector3 = new Vector3();
vector2.method(vector3) //Runtime error!
现在我有以下优点和缺点:
Vector
缺点:只有运行时错误我是否缺少使一个结构超过另一个结构的优点/缺点?
编辑:该库的主要目的是将其用于几何定义和openGL渲染。
拥有Set
界面和单独的实现类HashSet
,TreeSet
的原因是天才。它使所有代码尽可能通用,并使继承变得简单。它允许在将来扩展API,具有向后兼容性(对于其他类)。
而且还有一个Set
有一个特殊功能的问题:扩展SortedSet
的Set
界面,只有TreeSet
实现。
interface Vector {
}
class SparseVector implements Vector {
}
class UnitVector implements Vector {
}
interface IonicalVector extends Vector {
IonicalVector rotate(double phi);
}
class QuatrionsVector implements IonicalVector {
@Override
public IonicalVector rotate(double phi) { ... }
}
缺点是在LinkedList
的get(int index)
不适合它的开销。
我个人会继续简单的课程,当不同的实现是可以想到的,看看有什么意义。
请注意,您还可以使用builder pattern通过动态选择(私有)实现来实现一个接口。有点像Arrays.asList
。
Vector v = Vector.with().dim(4).quatrionic(true).build();
我理解你的意图。您希望使向量的维度成为编译时常量,并让编译器在维度适合时检入操作(如加法,标量乘法)。我过去曾经想过这些事情,但我无法找到一个好的解决方案。类型可以通过其他类型进行参数化,但不能通过数字进行参数化。
我的建议是摆脱类型定义中的所有数字。只需用字段Vector
定义一个类dimension
。然后,您可以检查每个操作的维度兼容性,只获得一个类(而不是n个不同的类)。这对于测试和维护代码来说是一个巨大的好处。缺点是维度问题导致运行时异常而不是编译问题。但是拥有清晰整洁的代码比这更重要。