我有三个代表音乐作品的非静态类。这些是分数,部分和注释类。
分数包含表示分数的多个乐器部分的实例变量ArrayList<Part>
,而Part包含表示音符序列的实例变量ArrayList<Note>
。
public class Score {
private ArrayList<Part> parts;
private int resolution;
public Score(int resolution) {
parts = new ArrayList<Part>();
this.resolution = resolution;
}
public void addPart(Part part) {
parts.add(part);
}
public ArrayList<Part> getParts() {
return parts;
}
public int getResolution() {
return resolution;
}
}
public class Part {
private ArrayList<Note> notes;
public Part() {
notes = new ArrayList<Note>();
}
public void addNote(Note note) {
notes.add(note);
}
public ArrayList<Note> getNotes() {
return notes;
}
}
public class Note() {
private long startStamp;
private long endStamp;
private int resolution;
public Note(long startStamp, long endStamp, int resolution) {
this.startStamp = startStamp;
this.endStamp = endStamp;
this resolution = resolution;
}
public double getDuration() {
int duration = (double) (getEndStamp() - getStartStamp()) / resolution;
return duration;
}
}
每个音符的持续时间使用分数分辨率计算。每次实例化注释时,都会通过Note construtor传递特定Score实例的解析。然后将注释添加到相应Part实例的ArrayList<Note> notes
,并将部分添加到Score实例的ArrayList<Part> parts
。
我使用int resolution
作为Note构造函数参数的解决方案似乎并不优雅,因为有许多笔记属于同一分数,即分辨率是分数的属性而不是笔记的属性。
有没有办法通过在Note类中引用相应的Score对象来获得解析,而不是通过Note类的构造函数或者其他解决方案传递解析?
答案 0 :(得分:2)
似乎分辨率与分数有关(基于您的设计),而不是注释 - 为什么不更改Note#getDuration的方法签名来计算特定分辨率的持续时间:
public double getDuration(int resolution) {
double duration = (double) (getEndStamp() - getStartStamp()) / resolution;
return duration;
}
现在可以将相同的注释添加到不同的分数,具有不同的分辨率。
甚至更好,你为什么不回复:
public long getDuration() {
return getEndStamp() - getStartStamp();
}
让调用代码处理它需要做的任何转换?
答案 1 :(得分:0)
要么通过将Score传递给Note构造函数来将它们紧紧地结合在一起,要么只是在Score本身中创建一个函数:getDuration(Node n)。这样只有得分会知道分辨率,这似乎更正确。 (假设分辨率确实是分数的属性。我对音乐一般都很愚蠢:()
编辑:
你肯定会更具描述性,例如:是的,贝多芬是愚蠢的,但如果他也是一名java程序员呢?:)
答案 2 :(得分:0)
何时需要计算持续时间?我个人试图避免在我的域对象中放置任何类型的逻辑,并且有一个服务计算所有三个对象之外的注释的持续时间,您可以在其中引用分数和注释。或许没有startStamp和endStamp属性,你可以使用startStamp和duration属性,并计算创建注释对象时的持续时间。
public class Note() {
private long startStamp;
private long duration;
public Note(long startStamp, long duration) {
this.startStamp = startStamp;
this.duration = duration;
}
public double getDuration() {
return duration;
}
}