Лучшая реализация, чтобы избежать, если / еще - PullRequest
3 голосов
/ 15 января 2020

Я делаю программу для отпуска в компании и время, которое разрешено быть в определенном c отпуске.

Я использовал класс Abstract с абстрактным методом:

public abstract class Abstract : TimeLength
{
    public AbstractTest(string employeeCode, string employee, string typeOfHoliday, DateTime startDate, DateTime endDate) : base(startDate, endDate, "")
    {
        TypeOfHoliday = typeOfHoliday;
        Employee = employee;
        EmployeeCode = employeeCode;
    }
    public string EmployeeCode { get; set; }
    public string Employee { get; set; }
    public string TypeOfHoliday { get; set; }

    public abstract bool HolidayValidation(string typeOfHoliday);
}

И я использовал несколько классов, которые присущи этому абстрактному классу, как эти два:

class MarriageVacation : Abstract
{
    public MarriageVacation(string employeeCode, string employee, string typeOfHoliday, DateTime startDate, DateTime endDate) : base(employeeCode, employee, typeOfHoliday, startDate, endDate)
    {
    }

    public override bool HolidayValidation(string typeOfHoliday)
    {
        if (Days() > (int)Holiday.MarriageVacation)
        {
            MessageBox.Show("Marriage Vacation Can only be 5 Days");
            return false;
        }
        else
            return true;
    }
}


class Bereavement : Abstract
{
    public Bereavement(string employeeCode, string employee, string typeOfHoliday, DateTime startDate, DateTime endDate) : base(employeeCode, employee, typeOfHoliday, startDate, endDate)
    {
    }

    public override bool HolidayValidation(string typeOfHoliday)
    {
        if (Days() > (int)Holiday.Bereavement)
        {
            MessageBox.Show("Bereavement Can only be 5 Days");
            return false;
        }
        else
            return true;
    }
}

Я использую Enum для праздников и в main Я хочу зарегистрировать это на основе пользователей такой выбор:

List<Abstract> holiday = new List<Abstract>();
if(CmbTypeHolidays.Text == Holiday.Bereavement.ToString())
        {
            var holid = new Bereavement(CmbEmpHolidays.Text.Split('-')[0], CmbEmpHolidays.Text.Split('-')[1], CmbTypeHolidays.Text, Convert.ToDateTime(StartDateHolidays.Value), Convert.ToDateTime(EndDateHolidays.Value));

            if (holid.HolidayValidation(CmbTypeHolidays.Text))
            {
                holiday.Add(holid);
                var bindingList = new BindingList<Abstract>(holiday);
                dataGridHolidays.DataSource = bindingList;
                controlPanelHolidays.Visible = false;
            }
        }
        else if (CmbTypeHolidays.Text == Holiday.MarriageVacation.ToString())
        {
            var holid = new MarriageVacation(CmbEmpHolidays.Text.Split('-')[0], CmbEmpHolidays.Text.Split('-')[1], CmbTypeHolidays.Text, Convert.ToDateTime(StartDateHolidays.Value), Convert.ToDateTime(EndDateHolidays.Value));

            if (holid.HolidayValidation(CmbTypeHolidays.Text))
            {
                holiday.Add(holid);
                var bindingList = new BindingList<Abstract>(holiday);
                dataGridHolidays.DataSource = bindingList;
                controlPanelHolidays.Visible = false;
            }
        }

Я хотел бы узнать лучший способ реализации этого решения или просто изменить код, который вставляет данные в абстрактный список

Ответы [ 3 ]

3 голосов
/ 15 января 2020

Вам потребуется настроить фабрику, которая отображает имя типа праздника в класс, реализующий его:

private class HolidayConstructorArgs {
    public string EmployeeCode {get;set;}
    public string Employee {get;set;}
    public string TypeOfHoliday {get;set;}
    public DateTime From {get;set;}
    public DateTime To {get;set;}
}

private static readonly IDictionary<string,Func<HolidayConstructorArgs,AbstractHoliday>> HolidayByTypeCode =
    new Dictionary<string,Func<HolidayConstructorArgs,AbstractHoliday>> {
        [$"{Holiday.Bereavement}"] = a => new Bereavement(a.EmployeeCode, a.Employee, a.TypeOfHoliday, a.From, a.To)
    ,   [$"{Holiday.MarriageVacation}"] = a => new MarriageVacation(a.EmployeeCode, a.Employee, a.TypeOfHoliday, a.From, a.To)
    };

Теперь вы можете получить фабрику из словаря и использовать ее для создания экземпляра объекта:

if (HolidayByTypeCode.TryGetValue(CmbTypeHolidays.Text, out var factory)) {
    // This is where the "magic" happens:
    // Func<> will invoke the appropriate constructor without a conditional
    var holid = factory(
        new HolidayConstructorArgs {
            EmployeeCode = CmbEmpHolidays.Text.Split('-')[0]
        ,   Employee = CmbEmpHolidays.Text.Split('-')[1]
        ,   TypeOfHoliday = CmbTypeHolidays.Text
        ,   From = Convert.ToDateTime(StartDateHolidays.Value)
        ,   To = Convert.ToDateTime(EndDateHolidays.Value)
        }
    );
    // ... The rest of your code remains the same
}
1 голос
/ 16 января 2020

Я внес эти изменения, основываясь на ответах на эти вопросы. Это Основной класс (Аннотация):

public class AbstractTest : TimeLength
{
    public AbstractTest(string employeeCode, string employee, Holiday typeOfHoliday, DateTime startDate, DateTime endDate) : base(startDate, endDate, "")
    {
        TypeOfHoliday = typeOfHoliday;
        Employee = employee;
        EmployeeCode = employeeCode;
    }
    public string EmployeeCode { get; set; }
    public string Employee { get; set; }
    public Holiday TypeOfHoliday { get; set; }

    public bool HolidayValidation(Holiday typeOfHoliday)
    {
        return Days() > (int)typeOfHoliday;
    }
}

А в Основной я изменился в это:

Holiday MyStatus = (Holiday)Enum.Parse(typeof(Holiday), CmbTypeHolidays.Text, true);
        var holid = new AbstractTest(CmbEmpHolidays.Text.Split('-')[0], CmbEmpHolidays.Text.Split('-')[1], MyStatus, Convert.ToDateTime(StartDateHolidays.Value), Convert.ToDateTime(EndDateHolidays.Value));

        if (!holid.HolidayValidation(MyStatus))
        {
            holiday.Add(holid);
            var bindingList = new BindingList<AbstractTest>(holiday);
            dataGridHolidays.DataSource = bindingList;
            controlPanelHolidays.Visible = false;
        }
        else
        {
            MessageBox.Show($"{holid.TypeOfHoliday} Cant be more than {(int)MyStatus} Days");
        }

Для typeOfHoliday я использовал Holiday типа, так что легче работать с и выбор, который пользователь делает, я конвертирую в Enum Holiday

1 голос
/ 15 января 2020

У вас такая же (почти) реализация для HolidayValidation, и вы не используете typeOfHoliday.

Из того, что вы опубликовали, вы также можете добавить перечисление Holiday в качестве параметра и свойства в базовый класс (Abstract) и вообще не иметь никакого наследования. Реализуйте HolidayValidation в базовом классе и используйте свойство Holiday для сравнения с Days

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...