2

我正在研究一组代表音符、小节、节奏等的类。当然,我必须处理最好用分数表示的拍号(如 4/4、3/4 等)。

我想知道什么是更好的风格。让 Bar 的构造函数包含一个分数对象或仅两个整数作为时间签名。

public Bar(Fraction timeSignature) {
    this.timeSignature = timeSignature;
}

或者:

public Bar (int num, int den) {
    timeSignature = new Fraction(num, den);
}

我的意思是……我可以两者兼得,但我应该在申请中选择哪一个?有没有“更好”的风格?

谢谢你的想法!

4

5 回答 5

5

就个人而言,我会采用第一种方法。如果你知道你需要/想要一个 Fraction 对象,为什么 Bar 不直接接受它?调用 Bar 类的人需要以任何一种方式理解 Fraction(将整数传递给您),所以它更简洁。

于 2013-01-09T14:51:29.877 回答
5

我会使用第一个并在分数类中提供一个工厂方法,以便能够调用类似的东西:

new Bar(Fraction.of(4, 4));

两全其美;-)

于 2013-01-09T14:53:24.870 回答
2

首先,简单的 API 很好,是的,但是如果您稍后扩展构造函数以获取更多参数(例如 BPM),使用原语而不是对象会使调用代码更难理解。IE:

Bar myBar = new Bar(4, 4) // Okay
Bar myBar = new Bar(4, 4, 120) // ??
Bar myBar = new Bar(new TimeSignature(4, 4), 120) // Much clearer

如有疑问,明确的更好。

其次,我想说不要将拍号存储在Fraction对象中——虽然它们通常被写成分数,但拍号不是。3/4 和 6/8 相当于分数,但它们是不同的拍号,因此会产生不同的声音。 TimeSignature在您的程序域内,它需要自定义类型。

于 2013-01-09T15:35:37.530 回答
2

您可能需要考虑将时间签名设为枚举,以防止用户输入错误。由于您可能有一组有限的拍号(2/4、6/8、4/4),您可以通过执行以下操作来控制用户创建的拍号:

//example
new Bar(TimeSignature.DUPLE_2_2)

public enum TimeSignature{

DUPLE_2_2(2,2), QUADRUPLE_2_4(2,4), TRIPLE_3_4(3,4);

private final int numerator;
private final int denominator;

private TimeSignature(int numerator, int denominator) {
this.numerator = numerator;
this.denominator = denominator;
}


}

祝你好运

于 2013-01-09T15:59:30.487 回答
1

与每个设计问题一样,这取决于。在这种情况下,您应该考虑如何使用您的类。

一般来说,我更喜欢更简单的 API。比较一下:

Bar myBar = new Bar(4, 4);

对此:

Bar myBar = new Bar(new Fraction(4,4));

后一种选择更明确(这很好),但如果你用文字参数实例化很多条,可能会变得乏味。另一方面,如果您的代码无论如何都需要处理分数,那么第一种语法可能会更好。

要考虑的另一个方面是引入新类的开销Fraction。创建一个额外的类只是为了存储两个ints 意味着很多开销而很少使用。但是,如果Fraction还提供其他服务(例如分数化简),则该类将获得其存在的权利。

于 2013-01-09T14:58:53.493 回答