重构为抽象类



我得到了一个新任务,将一些代码更改为更面向对象的内容,类似于之前提出的任务。

我正在读取一个配置文件,并获得一个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中实现每个代码片段。

最新更新