Как сделать разные типы проверки состояния объекта - PullRequest
0 голосов
/ 16 мая 2019

Мне нужно предоставить вызывающему абоненту записи из одного или двух разных источников данных и в пределах указанного диапазона дат или года.

Моя дилемма - использовать перегруженные методы или объект запроса с логикой проверки состояния.

Так что либо:

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 ]

1 голос
/ 16 мая 2019

Вы не должны использовать второй случай, поскольку он нарушает правило, согласно которому каждый класс должен иметь одну четко определенную ответственность.Здесь ваш класс отвечает за подробные диапазоны дат и диапазоны дат года.Если вы добавите больше критериев, этот класс превратится в нечто чудовищное.

Таким образом, вы можете использовать первый метод, как это делают многие люди.

Если вы хотите создать классы для инкапсуляции данных запроса, вы должны создатьбазовый абстрактный класс или интерфейс, а затем иметь различный тип подкласса запроса для каждого типа критериев, которые вы можете использовать.Например:

public interface Request {
    execute();
}

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

    public execute();

... etc
0 голосов
/ 17 мая 2019

Другое решение: используйте класс 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));
    }

    ...
}
...