Nice day to everybody.
I have an abstract class with the method runRandomExercise(), and several classes that extends it to add different kind of exercise.
I now want to chose a random type exercise, so I need to randomly choose one of the classes, and call runRandomExercise() on that.
For now I am manually coding this, which is not the very best solution I think. However, I can’t store just the classes in the array since the class type is different, and if I use object[] I can’t call the runRandomExercise() method. Any smart way to handle this?
Here is my code till now. It works, but it’s gonna be a pain to add other classes...
/*Specific classes that extend abstract class TrainingClass with the runRandomExercise() method*/
private MatheMagic mMathMag;
private Mnemonics mMnemonics;
private String[] mTrainingClasses;
/*Initialize classes*/
mMathMag = new MatheMagic();
mMnemonics = new Mnemonics();
/*Manually store classe names*/
mTrainingClasses = new String[2];
mTrainingClasses[0] = "mMathMag";
mTrainingClasses[1] = "mMnemonics";
/*Return random exercise*/
public String[] RandomExercise() {
Random aGenerator = new Random();
/*Get random class name*/
int rnd = aGenerator.nextInt(mTrainingClasses.length);
String aChosen = mTrainingClasses[rnd];
String[] aRes = new String[2];
if (aChosen == "mMathMag") {
aRes = mMathMag.runRandomExercise();
} else if (aChosen == "mMnemonics") {
aRes = mMnemonics.runRandomExercise();
}
return aRes;
}
EDIT Here is how TrainingClass is defined:
/** Common interface for all exercises */
public interface Exercise {
public String[] run();
}
/** Common interface for all training classes */
public abstract class TrainingClass {
private Random mRandGen = new Random();
public ArrayList<Exercise> mExerciseTypes = new ArrayList<Exercise>();
/** Run a random exercise */
public String[] runRandomExercise() {
int i = mRandGen.nextInt(mExerciseTypes.size());
return mExerciseTypes.get(i).run();
}
}
/*Specific training class*/
public class MatheMagic extends TrainingClass {
public MatheMagic() {
class SomeExercise implements Exercise {
public String[] run() {
String[] mRes = new String[2];
mRes[0] = "Question type 1";
mRes[1] = "Answer type 1";
return mRes;
}
}
class SomeOtherExercise implements Exercise {
public String[] run() {
String[] mRes = new String[2];
mRes[0] = "Question type 2";
mRes[1] = "Answer type 2";
return mRes;
}
}
SomeExercise mN = new SomeExercise();
SomeOtherExercise mS = new SomeOtherExercise();
mExerciseTypes.add(mN);
mExerciseTypes.add(mS);
}
}
Easy solution is to create an interface with the common method and have all your classes extend it.
Create a collection or array of that type instead of Object; you can simply iterate through or randomly select and call the method you want.
It feels like a Command pattern from GoF to me.
public interface Exercise {
void execute();
}
Now your classes do this:
public class MatheMagic implements Execise {
public void execute() {
// special logic here.
}
}
Then you can do this:
int numExercises = 1;
Exercise [] exercises = new Exercise[numExercises];
exercises[0] = new MatheMagic();
for (Exercise exercise : exercises) {
exercise.execute();
}