有更优雅的方式吗? (不能更具描述性。)

时间:2012-06-28 16:58:05

标签: java

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

分数包含表示分数的多个乐器部分的实例变量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类的构造函数或者其他解决方案传递解析?

3 个答案:

答案 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;
   }
}