Правильный способ настроить класс Date с проверкой

У меня есть класс следующим образом:

class Date
{
    // Field variables
    private int day;
    private int month;
    private int year;

    // Default constructor
    public Date()
    {
        year = 2015;
        day = 0;
        month = 0;
    }

    // Overloaded constructor
    public Date(int _day, int _month, int _year)
    {
        setDay(_day);
        setMonth(_month);
        setYear(_year);
    }

    // Accessors
    public int getDay()
    {
        return day;
    }

    public int getMonth()
    {
        return month;
    }

    public int getYear()
    {
        return year;
    }

    // Mutators
    public void setMonth(int _month)
    {
        if (_month > 0 && _month <= 12)
        {
            month = _month;
        }
    }

    public void setYear(int _year)
    {
        if (_year >= 1700 && _year <= 2015)
        {
            year = _year;
        }
    }

    public void setDay(int _day)
    {
        if (_day > 0 && _day <= DateTime.DaysInMonth(year, month))
        {
            day = _day;
        }
    }

Часть, которая не работает, проверяет мой день внутри метода setDay(). DateTime.DaysInMonth(year, month) (метод проверяет, сколько дней в конкретном месяце в данном году для учета високосных лет и февраля) вызывается из значения конструктора по умолчанию, равного 0, для месяцев до того, как данные пользователей/приложения проходят, чтобы назначить ему что-то между 1 и 12. Я не могу использовать DateTime для проверки всего этого, потому что приложение настроено так, что пользователи могут вводить 0 значений для дня или месяца, что, в свою очередь, не распечатывает день или месяц в окончательном формате.

Одно из предложений состояло в том, чтобы сделать мои сеттеры закрытыми и сделать один общедоступный метод setDate для пользователей, который позволит им устанавливать день, месяц и год в любом порядке... Но я не могу реализовать это правильно:

public void setDate(int _day, int _month, int _year)
{
    day = _day;
    month = _month;
    year = _year;
}

потому что это просто пропускает мою проверку в моих частных сеттерах.

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


person Justin Tennant    schedule 10.02.2015    source источник
comment
Измените порядок конструктора, чтобы сначала были установлены месяц и год. Если вы позволяете месяцу/году быть равным нулю, вы должны учитывать это в своей подпрограмме setDay.   -  person entropic    schedule 10.02.2015


Ответы (2)


Вы вызываете setDay (в своем конструкторе Overloaded) перед вызовом setMonth и setYear. Поскольку для использования DayaInMonth вам нужны год и месяц, вам нужно сначала вызвать эти установщики в своем конструкторе.

person David P    schedule 10.02.2015
comment
Спасибо! Не могу поверить, что просмотрел что-то подобное, но это именно моя проблема. - person Justin Tennant; 11.02.2015

Я публикую это, потому что я понял «предложение», которое я упомянул в своем первоначальном вопросе, из-за других замечательных ответов, которые я получил здесь. На всякий случай, если кто-то захочет сделать это таким образом.

Сохраняя конструкторы и все остальное в том же порядке, если я сделаю общедоступный сеттер для setDate() следующим образом:

public void setDate(int _day, int _month, int _year)
{
    setYear(_year);
    setMonth(_month);
    setDay(_day);
}

Я могу изменить исходные сеттеры на частные и вызывать их в любом указанном мной порядке (поскольку и setYear(), и setMonth() нужно вызывать до setDay()) через вызовы методов в общедоступном методе, а не просто напрямую присваивать значения переменным поля.

person Justin Tennant    schedule 10.02.2015