在创建对象时设置公共基类属性

时间:2015-06-17 15:25:20

标签: c#

在创建对象时,消除重复代码以设置基类属性的最佳方法是什么?请参阅下面的代码

public class  Employee
{
     public string DailyWorkHours { get; set; }
     public string WeeklyHolidays { get; set; }
}

public class ContractEmployee : Employee
{ 
      public string ContractDuration {get; set;}
}

public class FullTimeEmployee : Employee
{
     public string MonthlySalary {get; set; }
}

public class ContractEmployyeBuilder
{
   public void BuildObject ()
   {
        ContractEmployee emp = new ContractEmployee();
        emp.DailyWorkHours   = "8hours";
        emp.WeeklyHolidays  = "saturday and Sunday" ;
        emp.ContractDuration = "1 month" ;
   } 
}

public class FullTimeEmployeeBuilder
{
     public void BuildObject()
     {
          FullTimeEmployee emp = new FullTimeEmployee();
          emp.DailyWorkHours   = "8hours";
          emp.WeeklyHolidays   = "saturday and Sunday" ;
          emp.MonthlySalary    = "£2500";
     } 
}

从上面的代码中可以看出,ContractEmployyeBuilder和FullTimeEmployeeBuilder类的BuildObject方法负责创建相应的对象并填充其属性。

属于基类的两个属性,并且始终具有相同的值。这两个构建器类都重复了代码来完成这项工作。

我们如何重构这些Builder类,以便我们可以摆脱重复的代码来设置基类属性?

3 个答案:

答案 0 :(得分:1)

完整的分层和多态解决方案怎么样?面向对象的编程优点!

每个继承级别都可以直接调用基本的EmployeeBuilder实现! 这是优雅的解决方案

// Thanks to the generics power, each builder derived class
// will must provide the employee type to build, and it must be
// Employee or a derived of Employee class.
public class EmployeeBuilder<TEmployee>
    where TEmployee : Employee, new ()
{
    public virtual void BuildObject(TEmployee employee = null)
    {
        // If an instance is given as argument ok, if not 
        // one is created from scratch!
        TEmployee emp = employee ?? new TEmployee();
        emp.DailyWorkHours = "8hours";
        emp.WeeklyHolidays = "saturday and Sunday";
    }
}

public class ContractEmployeeBuilder<TEmployee> : EmployeeBuilder<TEmployee> where TEmployee : ContractEmployee, new ()
{
    public override void BuildObject(TEmployee employee = null)
    {
        // If an instance is given as argument ok, if not 
        // one is created from scratch!
        TEmployee emp = employee ?? new TEmployee();
        emp.ContractDuration = "1 month";
        base.BuildObject(emp);
    }
}

public class FullTimeEmployeeBuilder<TEmployee> : EmployeeBuilder<TEmployee> where TEmployee : FullTimeEmployee, new ()
{
    public override void BuildObject(TEmployee employee = null)
    {
        // If an instance is given as argument ok, if not 
        // one is created from scratch!
        TEmployee emp = employee ?? new TEmployee();
        emp.MonthlySalary = "£2500";
        base.BuildObject(emp);
    }
}

答案 1 :(得分:0)

base类中有一个构造函数,用于设置公共值:

public Employee()
{
    DailyWorkHours = "8hours";
    WeeklyHolidays = "saturday and Sunday";
}

DEMO

或者正如您在评论中提到的那样,您希望在构建器中设置值,您需要在基础中使用构造函数来获取参数:

public Employee(string dailyWorkHours, string weeklyHolidays)
{
    DailyWorkHours = dailyWorkHours;
    WeeklyHolidays = weeklyHolidays;
}

然后,派生类中的构造函数可以获取所述参数,然后调用基础构造函数:

public ContractEmployee (string dailyWorkHours, string weeklyHolidays) 
    : base(string dailyWorkHours, string weeklyHolidays)
{
}

答案 2 :(得分:0)

如下所示:

public class EmployeeBuilder
{
    public ContractEmployee BuildContractEmployee()
    {
        var emp = Create<ContractEmployee>();

        emp.ContractDuration = "1 month";

        return emp;
    }

    public FullTimeEmployee BuildFullTimeEmployee()
    {
        var emp = Create<FullTimeEmployee>();

        emp.MonthlySalary = "£2500";

        return emp;
    }

    private static T Create<T>() where T : Employee, new()
    {
        return new T {DailyWorkHours = "8hours", WeeklyHolidays = "saturday and Sunday"};
    }
}