Requesting feedback on my OO design
- by Prog
I'm working on an application that creates music by itself. I'm seeking feedback for my OO design so far. This question will focus on one part of the program.
The application produces Tune objects, that are the final musical products. Tune is an abstract class with an abstract method play. It has two subclasses: SimpleTune and StructuredTune.
SimpleTune owns a Melody and a Progression (chord sequence). It's play implementation plays these two objects simultaneously. StructuredTune owns two Tune instances. It's own play plays the two Tunes one after the other according to a pattern (currently only ABAB).
Melody is an abstract class with an abstract play method. It has two subclasses: SimpleMelody and StructuredMelody.
SimpleMelody is composed of an array of notes. Invoking play on it plays these notes one after the other. StructuredMelody is composed of an array of Melody objects. Invoking play on it plays these Melodyies one after the other.
I think you're starting to see the pattern. Progression is also an abstract class with a play method and two subclasses: SimpleProgression and StructuredProgression, each composed differently and played differently.
SimpleProgression owns an array of chords and plays them sequentially. StructuredProgression owns an array of Progressions and it's play implementation plays them sequentially.
Every class has a corresponding Generator class. Tune, Melody and Progression are matched with corresponding abstract TuneGenerator, MelodyGenerator and ProgressionGenerator classes, each with an abstract generate method. For example MelodyGenerator defines an abstract Melody generate method.
Each of the generators has two subclasses, Simple and Structured. So for example MelodyGenerator has a subclasses SimpleMelodyGenerator, with an implementation of generate that returns a SimpleMelody.
(It's important to note that the generate methods encapsulate complex algorithms. They are more than mere factory method. For example SimpleProgressionGenerator.generate() implements an algorithm to compose a series of Chord objects, which are used to instantiate the returned SimpleProgression).
Every Structured generator uses another generator internally. It is a Simple generator be default, but in special cases may be a Structured generator.
Parts of this design are meant to allow the end-user through the GUI to choose what kind of music is to be created. For example the user can choose between a "simple tune" (SimpleTuneGenerator) and a "full tune" (StructuredTuneGenerator). Other parts of the system aren't subject to direct user-control.
What do you think of this design from an OOD perspective? What potential problems do you see with this design? Please share with me your criticism, I'm here to learn.
Apart from this, a more specific question: the "every class has a corresponding Generator class" part feels very wrong. However I'm not sure how I could design this differently and achieve the same flexibility. Any ideas?