在调用类似Java类时去掉if/else

在调用类似Java类时去掉if/else,java,if-statement,switch-statement,Java,If Statement,Switch Statement,我有一个我想解决的问题,我需要解决一些其他情况。我在我的项目中获得了以下代码: if (ar[4].equals("week")) { WeekThreshold wt = new WeekThreshold(); firstTime = unparsedDate.format(wt.getStartDate().getTime()); secondTime = unparsedDate.format(wt.getEndDate().getTime()); } els

我有一个我想解决的问题,我需要解决一些其他情况。我在我的项目中获得了以下代码:

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());
}
三个类
WeekThreshold
MonthThreshold
YearThreshold
AbstractThreshold
类扩展而来,它们从日历中获取日期,但这并不重要。方法
quarterThreshold()
很特殊,可以保留在那里。但是,如果else阻塞并有一个语句调用不同的类,我怎么才能摆脱它呢


EDIT:忘了提到,需要调用的类来自各种数组
ar[]
。如果数组
ar[4]
是month,则必须调用
MonthThreshold
,等等。

多种可能性。。。XYZThreshold类是否有一个公共接口,如Threshold?然后你可以分配一个变量,例如

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块放入一个单独的类中。

您可以像下面这样将公共代码(
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());
}
AbstractThreshold at = ThresholdFactory.getThreshold(ar[4]);
if(at != null){
  firstTime = unparsedDate.format(at.getStartDate().getTime());
  secondTime = unparsedDate.format(at.getEndDate().getTime());
} else {
   quarterThreshold();
}
当然,过度设计的版本是可能的。下面只是一个示例,说明如何使用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();
}
//映射只能初始化一次,然后使用多次
Map thresholdSuppliers=新HashMap();
阈值供应商。放置(“周”,周阈值::新);
thresholdSuppliers.put(“月”,MonthThreshold::new);
阈值供应商。放置(“年”,年阈值::新);
AbstractThreshold at=thresholdSuppliers.getOrDefault(ar[4],()->null.get();
如果(at!=null){
firstTime=unparsedDate.format(位于.getStartDate().getTime());
secondTime=unparsedDate.format(at.getEndDate().getTime());
}如果(ar[4]。等于(“四分之一”))
四分之一阈值();
}

您可以使用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());

在这里,您可以充分利用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 = 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());
}
AbstractThreshold at = ThresholdFactory.getThreshold(ar[4]);
if(at != null){
  firstTime = unparsedDate.format(at.getStartDate().getTime());
  secondTime = unparsedDate.format(at.getEndDate().getTime());
} else {
   quarterThreshold();
}

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

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;
    }
}
公共类示例{
公共静态void main(字符串[]args){
字符串[]间隔={“周”、“周”、“季”、“月”、“年”、“周”};
IThreshold[]objects=新的IThreshold[interval.length];
//使用Factory模式创建对象
for(int index=0;index
首先创建阈值工厂

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;

你考虑过工厂设计模式吗?我的一位同事也这么告诉我,但我对oop很新鲜…我会用谷歌搜索它,当然任何提示也很好:)我会为你编写一些代码。。。给我一分钟如果你想摆脱命令式代码(
if
/
else
),你需要一个声明性的解决方案;使用
enum
。它们都使用相同的抽象类,是的。区别取决于您是否每次都想要一个新实例。如果不是,则可以使用一个实例true构造枚举。否则,您需要另一个版本,或者reflection.OP的问题似乎非常适合您在这里所描述的丰富的
enum
。比普通的基于
String
/
Map
的解决方案优雅得多。String-Switches仅适用于Java 7+,但这通常不是问题,只是想提一下。遗憾的是,不允许使用switch/case,因为它与if太相似/else@wg15music,谁不允许?主管,因为这些都是深入研究的练习OOP@wg15music,添加了一个新版本,只是为了让您的主管感到困惑:-)非常好用,谢谢!很好的代码来理解工厂是如何工作的:)@wg15music,请注意,您仍然有相同数量的if-else语句要删除。他们只是转移到单独的方法。但是我被告知我可以使用工厂模式…我可能可以添加一些枚举或哈希映射…但最终我无法完全摆脱它们,对吗?他们一定是某个人