java - 良好的面向对象设计

标签 java oop

问题和答案有层次结构:

class Answer
{
  int doubtLevel;
}
class YesNoAnswer extends Answer
{
  boolean isYes;
}
class ColorAnswer extends Answer
{
  int red;
  int green;
  int blue;
}

class Question
{
  Context ctx;
  abstract List<? extends Answer> answers;
}
class DoesItWorkQuestion extends Question
{
  Thing it;
  List<YesNoAnswer> answers;
}
class IsItTastyQuestion extends Question
{
  Dish dish;
  List<YesNoAnswer> answers;
}
class FavoriteColorQuestion extends Question
{
  List<ColorAnswer> answers;
}

首先,我不喜欢在每个具体类中包含答案列表只是为了修复答案的类型。有没有办法定义一个结构来将答案列表保留在问题之外?但问题的答案类型必须是固定的。

然后我需要创建为问题中的每个答案保存一个值的结构,例如假设我想要一个计算器来计算每个答案的概率:

class AnswerProbability<Q extends Question>
{
  Q question;
//??
   double getProbability(???Answer answer){...}
}
class ProbabilityCalculator
{
  //  different params may produce different answer lists 
  //(e.g. if probability of an answer is less than 1%, don't include 
  //the answer in the list).
  AnswerProbability<IsItTastyQuestion> tastyQuestionProbability(String param1, String param2);
  AnswerProbability<FavoriteColorQuestion> favoriteColorQuestion(String param);
...
}
...

以及如何使用它:

AnswerProbability<IsItTastyQuestion> prob = calculator.tastyQuestionProbability(...);
// I want the "get" method take only YesNoAnswer type.
println(prob.get(new YesNoAnswer(true, 10) + prob.get(new YesNoAnswer(false, 5));
// or:
for(YesNoAnswer ans : prob.question.answers)
{
  if(ans.isYes)
    println(prob.get(ans));
}
// Also I need work with superclasses
List<AnswerProbability> aps;
aps.add(calculator.calculateTastyQuestionProbability("soup", "mushroom"));
aps.add(calculator.calculateFavoriteColorQuestion("socks"));
..
// use `doubtLevel` from the `Answer` superclass.
for(AnswerProbability ap : aps)
{
  for(Answer a : ap.question.answers)
  {
    if(a.doubtLevel < 5)
      println(ap.get(a));
  }
}

所以,我想避免类型转换和运行时检查。

最佳答案

你不能有抽象字段。您可以在此处使用泛型

class Question<A extends Answers> {
  Context ctx;
  final List<A> answers = new ArrayList<A>();
}

class DoesItWorkQuestion extends Question<YesNoAnswer> {
  Thing it;
}

class FavoriteColorQuestion extends Question<ColorAnswer> {
}

但是我怀疑记录每个答案的计数会更有用。

class Question<A extends Answers> {
  Context ctx;
  final Map<A, Integer> answerCounts = new HashMap<>();
}

class DoesItWorkQuestion extends Question<YesNoAnswer> {
  Thing it;
}

class FavoriteColorQuestion extends Question<ColorAnswer> {
}

// later
for(Entry<YesNoAnswer, Integer> ansCount : prob.question.answers.entrySet()) {
    switch(ansCount.getKey()) {
       case YES:
          int count = ansCount.getValue();
          // something
          break;
    }
}

这更有效,因为大小与可能答案的数量成正比,而不是答案的数量,并且计算概率非常容易。

关于java - 良好的面向对象设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8593797/

相关文章:

java - 使用Jxls生成pdf

java - ODBC 到 JDBC 数据类型的映射

python - 如何子类化 matplotlib 的图形类?

c# - 如何处理 catch block 中的异常?

PHP, OOP, 静态

perl - perl 中的继承和默认构造函数

java - 在 Java 中从套接字读取字节

java - Spring Boot Jackson 日期格式

java - 如何使用 spring 添加多个谷歌云数据源

C++ 跟踪类内的变化