【问题标题】:Better way to call common method on randomly selected object in java在java中随机选择的对象上调用通用方法的更好方法
【发布时间】:2012-09-03 23:31:51
【问题描述】:

祝大家有美好的一天。

我有一个带有 runRandomExercise() 方法的抽象类,以及几个扩展它以添加不同类型练习的类。

我现在想选择一个随机类型的练习,所以我需要随机选择其中一个类,然后调用 runRandomExercise()。

目前我正在手动编写此代码,这不是我认为的最佳解决方案。但是,由于类类型不同,我不能只将类存储在数组中,如果我使用 object[],我就不能调用 runRandomExercise() 方法。有什么聪明的方法来处理这个吗?

这是我到目前为止的代码。它可以工作,但是添加其他类会很痛苦......

/*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;
}

编辑 以下是 TrainingClass 的定义方式:

/** 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);
 } 

}

【问题讨论】:

    标签: java architecture random coding-style arrayobject


    【解决方案1】:

    简单的解决方案是使用通用方法创建一个接口,并让所有类扩展它。

    创建该类型的集合或数组而不是 Object;您可以简单地迭代或随机选择并调用您想要的方法。

    对我来说,这感觉就像 GoF 的命令模式。

    public interface Exercise {
        void execute();
    }
    

    现在你的班级会这样做:

    public class MatheMagic implements Execise {
        public void execute() {
            // special logic here.
        }
    }
    

    那么你可以这样做:

    int numExercises = 1;
    Exercise [] exercises = new Exercise[numExercises];
    exercises[0] = new MatheMagic();
    for (Exercise exercise : exercises) {
        exercise.execute();
    }
    

    【讨论】:

    • 如果我理解正确,它就不能在抽象类上工作,对吧?因此,这意味着我需要在每个类中重写 runRandomExercise() 方法,这将使我回到第一步。还是有我没有看到的转机?
    • 我编辑了问题以显示 TrainingClass 是如何定义的。
    • 为什么不呢?只需使您需要子类的类覆盖抽象即可。我说的其他一切都有效。接口只是意味着更好的混合行为;它们也适用于您希望其中一个类扩展其他内容的情况。
    • 我不明白我可以创建一个 TrainingClass[] 数组,并用子类填充它。谢谢!
    【解决方案2】:

    是的,是的,您可以将所有这些类存储在一个数组中,然后随机调用它们。如何?创建一个接口,并在所有类中派生自该接口。这样您就可以基于接口调用,而不是基于实现调用。

    【讨论】:

    • duffymo 领先我几秒。
    猜你喜欢
    • 2012-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多