我得到了一个新任务,将一些代码更改为更面向对象的内容,类似于之前提出的任务。
我正在读取一个配置文件,并获得一个Array ar[]。ar[4]包含周、月、季度或年。这是用一些糟糕的编程技巧完成的
if (ar[4].equals("week")) {
weekThreshold();
} else if (ar[4].equals("month")) {
monthThreshold();
} else if (ar[4].equals("quarter")) {
quarterThreshold();
} else if (ar[4].equals("year")) {
yearThreshold();
}
其中两种方法称为
public void weekThreshold() {
cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
firstTime = unparsedDate.format(cal.getTime());
cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
secondTime = unparsedDate.format(cal.getTime());
}
public void monthThreshold() {
limitGiven = limitGiven * 4;
cal.set(Calendar.DAY_OF_MONTH,Calendar.getInstance().getActualMinimum(Calendar.DAY_OF_MONTH));
firstTime = unparsedDate.format(cal.getTime());
cal.set(Calendar.DAY_OF_MONTH,Calendar.getInstance().getActualMaximum(Calendar.DAY_OF_MONTH));
secondTime = unparsedDate.format(cal.getTime());
}
这些变量firstTime和secondTime最终用于SQL查询。
我现在的任务是创建一个类抽象阈值来删除if/else情况。从这个AbstractThreshold中可以得到WeekThreshold、MonthThreshold等类
如何将Threshold方法切换到抽象类,并再次使用正确的方法创建新的类?这让我很困惑:(
这肯定更适合像CodeReview这样的东西,但我会试一试:
我将首先尝试确定这些对象有什么共同点,在您的情况下,它是firstTime
&lastTime
,这样我们就可以构造一个抽象类如下:
public abstract class DateThreshold {
private final Calendar initial;
// you can also have a string constructor here to parse your date
protected DateThreshold(final Date date) {
this.calendar = Calendar.getInstance();
this.calendar.setTime(date);
}
private Calendar getInitial() {
return (Calendar) this.initial.clone();
}
public abstract Calendar getStartDate();
public abstract Calendar getEndDate();
}
现在您可以开始实现不同类型的阈值,例如:
public static DateThreshold weekThreshold(final Date date) {
return new RelativeDate(date) {
@Override
public Calendar getStartDate() {
final Calendar cal = super.getCalendar();
cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
return (Calendar) cal;
}
@Override
public Calendar getEndDate() {
final Calendar cal = super.getCalendar();
cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
return (Calendar) cal;
}
};
}
要使用新的DateThreshold
,您可以这样做:
final DateThreshold week = weekThreshold(new Date());
week.getStartDate();
week.getEndDate();
这显然是未经测试的,但应该会给您一个好主意
这类反模式的正常重构是引入enum
。
enum Threshold {
Week {
@Override
void getThreshold() {
}
},
Month {
@Override
void getThreshold() {
}
},
Quarter {
@Override
void getThreshold() {
}
},
Year {
@Override
void getThreshold() {
}
};
abstract void getThreshold();
private static Map<String, Threshold> thresholds = new HashMap<>();
static Threshold lookup(String name) {
if (thresholds.isEmpty()) {
// Populate.
for (Threshold t : Threshold.values()) {
thresholds.put(t.name().toLowerCase(), t);
}
}
return thresholds.get(name);
}
}
public void test() {
String[] ar = {"A", "B", "c", "5", "week"};
Threshold.lookup(ar[4]).getThreshold();
}
现在,您可以在enum
中实现每个代码片段。