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 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
Melody is an abstract class with an abstract
play method. It has two subclasses:
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:
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
Progression are matched with corresponding abstract
ProgressionGenerator classes, each with an abstract
generate method. For example
MelodyGenerator defines an abstract
Melody generate method.
Each of the generators has two subclasses,
Structured. So for example
MelodyGenerator has a subclasses
SimpleMelodyGenerator, with an implementation of
generate that returns a
(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
Structured generator uses another generator internally. It is a
Simple generator be default, but in special cases may be a
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.
My question regarding this design is rather specific:
When I look at my design, it looks like the design-equivalent of 'code duplication': 'class-duplication' or 'design-duplication'. You can clearly see what I'm referring to if you look at the above diagram.
My question is split into two:
- Is my intuition correct? Is this duplication, or reoccuring pattern in the design, a bad thing?
- If it is, how can I design this differently and more efficiently?