Java 重构到抽象类

Java 重构到抽象类,java,oop,abstract,Java,Oop,Abstract,我得到了一个新任务,将一些代码更改为更面向对象的内容,类似于之前的任务 我正在读取一个配置文件并获取一个数组ar[]。ar[4]包含周、月、季度或年。这是用一些糟糕的编程技巧完成的 if (ar[4].equals("week")) { weekThreshold(); } else if (ar[4].equals("month")) { monthThreshold(); } else if (ar[4].equals("quarter")) { quarterThr

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

我正在读取一个配置文件并获取一个数组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查询

我现在的任务是创建一个类AbstractThreshold来删除if/else案例。从这个抽象的阈值开始,类WeekThreshold,MonthThreshold等等


如何将阈值方法切换到抽象类,并再次使用正确的方法生成新类?这让我很困惑:(

这肯定更适合这样的东西,但我会尝试一下:

我将首先尝试确定这些对象的共同点,在您的例子中是
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阈值{
周{
@凌驾
void getThreshold(){
}
},
月{
@凌驾
void getThreshold(){
}
},
四分之一{
@凌驾
void getThreshold(){
}
},
年{
@凌驾
void getThreshold(){
}
};
抽象void getThreshold();
私有静态映射阈值=新HashMap();
静态阈值查找(字符串名称){
if(thresholds.isEmpty()){
//填充。
对于(阈值t:Threshold.values()){
thresholds.put(t.name().toLowerCase(),t);
}
}
返回阈值。get(name);
}
}
公开无效测试(){
字符串[]ar={“A”,“B”,“c”,“5”,“week”};
Threshold.lookup(ar[4]).getThreshold();
}

你现在可以在
enum

中实现你的每个代码片段,做这个简短的教程,然后用你已经尝试过的内容更新你的问题。然后来这里提问。我会试试看,乍一看非常棒,但是你确定有私人最终日历吗?我实际上对最终的日历有问题。还有,DateThreshold方法中未使用来自首字母的名称:)
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();
}