如何进行不同类型的对象状态验证

时间:2019-05-16 12:55:53

标签: java validation design-patterns object-state

我需要在一个指定的日期范围或年份范围内,从一个或两个不同的数据源向呼叫者提供记录。

我的难题是我应该使用重载方法还是带有状态验证逻辑的Request对象。

所以:

public List<Record> getRecords (Date fromDate, Date toDate, boolean dataSourceARequired, boolean dataSourceBRequired)

public List<Record> getRecords (int fromYear, int toYear, boolean dataSourceARequired, boolean dataSourceBRequired)

或类似的内容:

public List<Record> getRecords(Request request)

其中的请求看起来像:

public class Request{

private final Date fromDate;
private final Date toDate;
private final int fromYear;
private final int toYear;
private final boolean dataSourceARequired;
private final boolean dataSourceBRequired;



public Request(Date fromDate, Date toDate, boolean dataSourceARequired, boolean dataSourceBRequired){

    if (fromDate == null) {
        throw new IllegalArgumentException("fromDate can't be null");
        }
     if (toDate == null) {
        throw new IllegalArgumentException("toDate can't be null");
        }
    if (!dataSourceARequired && !dataSourceBRequired){
        throw new IllegalStateException ("No data source requested");
        }
     if (fromDate.after(toDate)){
         throw new IllegalStateException ("startDate can't be after    endDate");
        }

     this.fromDate = fromDate;
     this.toDate = toDate;
     this.dataSourceARequired = dataSourceARequired;
     this.dataSourceBRequired = dataSourceBRequired;
     this.fromYear = -1;
     this.toYear = -1;

}


 public Request(int fromYear, int toYear, boolean dataSourceARequired, boolean dataSourceBRequired){

    if (fromYear > toYear) {
        throw new IllegalArgumentException("fromYear can't be greater than toYear");
        }
    if (!dataSourceARequired && !dataSourceBRequired){
        throw new IllegalStateException ("No data source requested");
        }

     this.dataSourceARequired = dataSourceARequired;
     this.dataSourceBRequired = dataSourceBRequired;
     this.fromYear = fromYear;
     this.toYear = toYear;
     this.fromDate = null;
     this.toDate = null;

}

}

还是有另一种方法?

2 个答案:

答案 0 :(得分:1)

您不应使用第二种情况,因为这违反了每个类都应负有明确定义的责任的规则。在这里,您的课程负责详细的日期范围和年份日期范围。如果您添加更多条件,该课程将发展为可怕的课程。

因此您可以使用第一种方法,很多人都可以使用。

如果要创建用于封装请求数据的类,则应创建一个基本抽象类或接口,然后针对每种可以使用的条件类型使用不同的请求子类。例如:

public interface Request {
    execute();
}

public class YearRangeRequest implements Request {
    int fromYear;
    int toYear;

    public execute();

... etc

答案 1 :(得分:0)

另一种解决方案:将DateRange类与两个构造函数一起使用:

public class DateRange {
    final Date start;
    final Date end;

    public DateRange(Date start, Date end) {
        this.start = start;
        this.end = end;
    }

    public DateRange(int startYear, int endYear) {
        this(yearBegining(startYear), yearBegining(endYear));
    }

    ...
}