4

我有三个代表音乐作品的非静态类。这些是分数,部分和音符类。

Score 包含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 然后添加到ArrayList<Note> notes对应的 Part 实例,part 添加到ArrayList<Part> partsScore 实例。

我使用int resolutionNote 构造函数参数的解决方案似乎并不优雅,因为有许多音符属于同一乐谱,即分辨率是乐谱的属性而不是音符的属性。

有没有办法通过从 Note 类内部引用相应的 Score 对象来获得分辨率,而不是通过 Note 类的构造函数或其他解决方案传递分辨率?

4

3 回答 3

2

似乎分辨率与分数有关(基于您的设计),而不是与注释有关 - 为什么不更改 Note#getDuration 的方法签名以计算特定分辨率的持续时间:

public double getDuration(int resolution) {
  double duration = (double) (getEndStamp() - getStartStamp()) / resolution;
  return duration;

}

同一个音符现在可以添加到不同的乐谱中,具有不同的分辨率。

或者更好的是,你为什么不简单地返回:

public long getDuration() {
  return getEndStamp() - getStartStamp();

}

并让调用代码处理它需要做的任何转换?

于 2012-06-28T17:07:30.617 回答
0

什么时候需要计算持续时间?我个人尽量避免在我的域对象中放置任何类型的逻辑,并且会让服务计算所有三个对象之外的音符的持续时间,您可以在其中引用乐谱和音符。也许您可以拥有 startStamp 和 duration 属性并在创建便笺对象时计算持续时间,而不是拥有一个 startStamp 和一个 endStamp 属性。

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;
   }
}
于 2012-06-28T17:24:21.637 回答
0

要么通过将 Score 传递给 Note 构造函数将它们紧密结合,要么只在 Score 本身中创建一个函数:getDuration(Node n)。这样只有分数会知道分辨率,这似乎更正确。(假设分辨率确实是分数的一个属性。我一般对音乐很笨:()

编辑:

你当然可以更详细地描述,例如这个标题:是的,贝多芬很笨,但如果他也是一个 java 程序员呢?:)

于 2012-06-28T17:05:22.193 回答