调用类似的类Java

时间:2015-08-12 12:12:41

标签: java if-statement switch-statement

我有我想要的问题,需要摆脱一些if else案例。我在我的项目中获得了以下代码:

if (ar[4].equals("week")) {

    WeekThreshold wt = new WeekThreshold();
    firstTime = unparsedDate.format(wt.getStartDate().getTime());
    secondTime = unparsedDate.format(wt.getEndDate().getTime());

} else if (ar[4].equals("month")) {

    MonthThreshold mt = new MonthThreshold();
    firstTime = unparsedDate.format(mt.getStartDate().getTime());
    secondTime = unparsedDate.format(mt.getEndDate().getTime());

} else if (ar[4].equals("quarter")) {

    quarterThreshold();

} else if (ar[4].equals("year")) {

    YearThreshold yt = new YearThreshold();
    firstTime = unparsedDate.format(yt.getStartDate().getTime());
    secondTime = unparsedDate.format(yt.getEndDate().getTime());
}

这三个课程WeekThresholdMonthThresholdYearThreshold来自AbstractThreshold课程,他们从日历中获取日期,但这并不重要。方法quarterThreshold()很特别,可以留在那里。但是,我怎么能摆脱那个if else块并且有一个语句来调用不同的类?

编辑:忘记提及,需要调用的类来自各种数组ar[]。如果数组ar[4]为月,则必须调用MonthThreshold

6 个答案:

答案 0 :(得分:4)

多种可能性...... XYZThreshold类是否具有通用接口,如阈值?然后你可以用它来分配一个变量,例如......

Threshold threshold = null;
if ((ar[4].equals("week")) {
  threshold = new WeekThreshold();
} else ... {

}

firstTime = unparsedDate.format(threshold.getStartDate().getTime());
secondTime = unparsedDate.format(threshold.getEndDate().getTime());

这将是第一步。如果您愿意,您可以使用枚举来存储阈值:

enum Thresholds {
  WEEK("week") {

     public Threshold getThreshold() {
           return new WeekThreshold();
     }
  },
  etc.

  private String period;

  private Thresholds(String period) {
    this.period = period;
  }

  public abstract Threshold getThreshold();

  //  ...add a static class to iterate and search by period, 
  // ...so you can write Threshold threshold = Thresholds.getByPeriod("week").getThreshold();
}

使用枚举是个人品味,当然,您可以使用普通类或仅将阈值选择的if-block放入单独的类中来执行相同的操作。

答案 1 :(得分:4)

您可以将公共代码(unparsedDate.format(...))合并到外面,如下所示:

AbstractThreshold at = null;
switch(ar[4]) {
case "week":
    at = new WeekThreshold();
    break;
case "month":
    at = new MonthThreshold();
    break;
case "year":
    at = new YearThreshold();
    break;
case "quarter":
    quarterThreshold();
    break;
}
if(at != null) {
    firstTime = unparsedDate.format(at.getStartDate().getTime());
    secondTime = unparsedDate.format(at.getEndDate().getTime());
}

当然可以使用过度设计的版本。这里只是说明如何使用Java-8功能实现它:

// Map can be initialized only once, then used many times
Map<String, Supplier<AbstractThreshold>> thresholdSuppliers = new HashMap<>();
thresholdSuppliers.put("week", WeekThreshold::new);
thresholdSuppliers.put("month", MonthThreshold::new);
thresholdSuppliers.put("year", YearThreshold::new);

AbstractThreshold at = thresholdSuppliers.getOrDefault(ar[4], () -> null).get();
if(at != null) {
    firstTime = unparsedDate.format(at.getStartDate().getTime());
    secondTime = unparsedDate.format(at.getEndDate().getTime());
} else if(ar[4].equals("quarter"))
    quarterThreshold();
}

答案 2 :(得分:2)

在这里,您可以充分利用FactoryPattern

class ThresholdFactory
{
  public static AbstractThreshold getThreshold(String criteria)
  {
    if ( criteria.equals("week") )
      return new WeekThreshold();
    if ( criteria.equals("month") )
      return new MonthThreshold();
    if ( criteria.equals("year") )
      return new YearThreshold();

    return null;
  }
}

其余的代码看起来像这样:

AbstractThreshold at = ThresholdFactory.getThreshold(ar[4]);
if(at != null){
  firstTime = unparsedDate.format(at.getStartDate().getTime());
  secondTime = unparsedDate.format(at.getEndDate().getTime());
} else {
   quarterThreshold();
}

答案 3 :(得分:2)

以下是如何使用接口和工厂设计模式的示例 如果您的多个实现者共享公共代码,请让它们都扩展一个实现该接口的Abstract类。通过接口引用您的方法是个好主意,而不是利用多态性的具体类...请参阅下面的代码...

public class Example {

    public static void main(String[] args) {

        String[] intervals = {"week", "week", "quarter", "month", "year", "week"}; 

        IThreshold[] objects = new IThreshold[intervals.length];

        // Create your objects using Factory pattern
        for(int index = 0; index < intervals.length; index++) {
            objects[index] = ThresholdFactory.createInstance(intervals[index]);
        }

        // Now iterate through your objects and refer to them through a common interface
        for(IThreshold object : objects) {
            int start = object.getFirstTime();
            int end = object.getFirstTime();
        }
    }
}

interface IThreshold {
    public int getFirstTime();
    public int getLastTime();
}


abstract class AbstractThreshold implements IThreshold {

    @Override
    public int getFirstTime() {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public int getLastTime() {
        // TODO Auto-generated method stub
        return 0;
    }

}

class WeekThreshold extends AbstractThreshold {}
class MonthThreshold extends AbstractThreshold {}
class QuarterThreshold extends AbstractThreshold {}
class YearThreshold extends AbstractThreshold {}

class ThresholdFactory {

    public static final IThreshold createInstance(String interval) {
        IThreshold instance = null;

        if(interval.equals("week")){
            instance = new WeekThreshold();
        } 
        else if(interval.equals("month")){
            instance = new MonthThreshold();
        } 
        else if(interval.equals("quarter")){
            instance = new QuarterThreshold();
        } 
        else {
            if(interval.equals("year")){
                instance = new YearThreshold();
            }
        }
        return instance;
    }
}

答案 4 :(得分:2)

首先创建阈值工厂,

static enum ThresholdsFactory {


        week(new WeekThreshold()), month(new MonthThreshold())/* etc */;

        static private Map<String,ThresholdsFactory> lookup = new HashMap<String, ThresholdsFactory>();
        static{
            for(ThresholdsFactory val :  ThresholdsFactory.values()){
            lookup.put(val.name(), val);
            }
        }

        public AbstractThreshold threshold;

        public static ThresholdsFactory find(String name){
            return lookup.get(name);
        }

        ThresholdsFactory(AbstractThreshold th) {
            threshold = th;

}     }

现在您需要做的就是

AbstractThreshold th = ThresholdsFactory.find(ar[4]);

if (th!=null){
    firstTime = unparsedDate.format(th.getStartDate().getTime());
    secondTime = unparsedDate.format(th.getEndDate().getTime());
}

答案 5 :(得分:0)

您可以使用switch语句

String typeOfDay;
     switch (dayOfWeekArg) {
         case "Monday":
             typeOfDay = "Start of work week";
             break;
         case "Tuesday":
         case "Wednesday":
         case "Thursday":
             typeOfDay = "Midweek";
             break;
         case "Friday":
             typeOfDay = "End of work week";
             break;
         case "Saturday":
         case "Sunday":
             typeOfDay = "Weekend";
             break;
         default:
             throw new IllegalArgumentException("Invalid day of the week: " + dayOfWeekArg);
     }

您可以使用自己的代码替换我从java文档中窃取的示例

switch(periodType){
    case "week":
      WeekThreshold wt = new WeekThreshold();
    break; // add your other cases
}
firstTime = unparsedDate.format(wt.getStartDate().getTime());
secondTime = unparsedDate.format(wt.getEndDate().getTime());