在调用类似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语句要删除。他们只是转移到单独的方法。但是我被告知我可以使用工厂模式…我可能可以添加一些枚举或哈希映射…但最终我无法完全摆脱它们,对吗?他们一定是某个人