我正在尝试创建一些简单的类来完成OpenGL转换所需的数学运算。然而,现在我已经走了一半,在查看不同的例子时,我发现大多数库都将数学与矩阵类本身分开(大多数时候在数学类中使用静态方法)。究竟是什么原因?
当您创建多个矩阵对象时,多次创建函数会影响性能还是完全不同?
实施例: 我发现将数学函数添加到矩阵类更容易,因此我不需要将矩阵本身传递给函数:例如。
class Matrix4f {
//constructor...
public void rotate(double theta) {
setValue(0, 0, (float) Math.cos(theta));
setValue(1, 0, (float) Math.sin(theta));
setValue(0, 1, (float) Math.sin(theta));
setValue(1, 1, (float) Math.cos(theta));
}
//getters and setters...
}
而不是
public class LinearAlgebraMath {
public static Matrix4f rotate(Matrix4f target, double theta) {
target.setValue(0, 0, (float) Math.cos(theta));
target.setValue(1, 0, (float) Math.sin(theta));
target.setValue(0, 1, (float) Math.sin(theta));
target.setValue(1, 1, (float) Math.cos(theta));
return target;
}
}
public class Matrix4f {
//constructor...
//getters and setters...
}
所以,最后我喜欢将数学函数添加到矩阵类中,因为它对我来说更容易(特别是在处理使用多个数据结构的数学运算时),但我不希望我的偏好性能降低,所以我的问题是:下面的例子是否胜过上面的例子,如果是,为什么?
答案 0 :(得分:1)
当你创建多个矩阵对象时,是吗? 功能也会多次创建,这会影响性能 或完全不同的东西?
这些函数是加载到VM中的Class
对象的一部分。多个Matrix
对象仅引用该函数/方法的一个副本。因此,您建议使用实例方法不会影响内存等。
我通常会将功能附加到类的实例,正如您所建议的那样。也许您正在使用的引用是从非OO语言(C?)翻译的,其中结构用于矩阵和独立函数是强制性的?
答案 1 :(得分:0)
非成员具有实际利益,他们有更松散的耦合。他们不能修改班级的内部,可以这么说。
例如,如果您遇到一个用户报告的错误,其中应用程序使用与矩阵相关的代码抛出一般数组访问超出范围异常(不是特定于矩阵类的异常),那么如果您有一个非常简单的矩阵类,只有一些方法,可能会弄乱它的生殖器(私人)并给它STDs,你的矩阵睡觉的嫌疑人名单非常狭窄。与此同时,如果你有一个200个方法的矩阵类,它会参与派对,喝醉并睡觉,那么你所研究的嫌疑人名单就很大了。
如果它不能提供已知的每个与矩阵相关的操作,那么您的矩阵类可以更快地实现代码稳定性(如在具体中粘合,缺乏进一步改变的理由)。人。在设计任何东西时,这非常有用,以确保公共界面具有真正完成"完成"在那里你没有感受到回归的诱惑,并且无限期地添加越来越多的东西到你有一个拥有100多种方法的类的野兽,文档必须跨越20页。能够将您的代码库分成稳定(不变)和不稳定(变化)的部分是件好事,所以对于任何设计,您都应该能够实现“完整性”状态"至于它提供的功能是非常有限的 时间量。
旨在添加所有可能的操作,你可以用类进入类本身通常会使实现这样的目标变得不可能。您越来越多地添加到课程中,您越来越多地找到添加更多内容的理由。那里有一个恶性循环,你添加的越多,你的设计看起来就越不完整。极简主义是对抗这一目标的方法。
最后,它使您的矩阵类更容易理解如何使用它,因为你可以用它来做更少的事情。有些人可能对特征向量/值不感兴趣,因此如果它提供的功能较少,可能有助于使界面更易于理解。
一种实用的方法是将基本操作包含在您的设计中,使所有背景的人都能一直这样做,如矩阵/矩阵和矩阵/向量乘法。在那里你仍然可以有一个清单,你可以在那里打电话给设计"完成"在某些时候,没有设计一个神级/巨石,旨在做世界上可以想象的一切。然后将异国情调的东西放入单独的接口中,例如使用静态方法的单独类,这些类只能通过矩阵的公共接口进行操作。那些单独的静态方法无法访问内部,因此它们可以通过一个安全层,你的矩阵类可以强加不变量,不允许其内部数据被访问超出界限而不抛出{{1异常或此类效果。
在你的情况下,我认为它只是一个一对一的OpenGL翻译,这是一个C API,方法是不可能的,但值得注意的是,非成员优于一般软件工程学的耦合和凝聚力的立场。它们在语法上可能更麻烦,但是从维护和调试的角度来看,可以访问你班级私有的东西越少越好。太多的方法和你的私有变得类似于全局变量,因为它们有如此多的东西可能会篡改它们的史诗范围/可见性。在设计任何语言的类时要记住这一点 - 如果可以仅使用该类的公共接口在其他地方实现,则查找省略直接向类添加内容的理由。出于类似的原因,如果您可以避免从类继承以访问其受保护的成员,那么从SE的角度来看,组合优于这些上下文中的继承,因为它会产生更松散的耦合。
从性能角度来看,将方法直接添加到类中往往有更多理由,因为最有效的解决方案可能需要访问类的内部。在事后添加一种新方法时,如果对它有强烈的感知需求,而不是事先在课堂上添加大量不必要的方法,那么最好还是犯错误。我喜欢遵循&#34的简单规则;如果有疑问,请将其排除在外。当谈到我是否应该向接口添加方法时。