在创建对象时,消除重复代码以设置基类属性的最佳方法是什么?请参阅下面的代码
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类,以便我们可以摆脱重复的代码来设置基类属性?
答案 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";
}
或者正如您在评论中提到的那样,您希望在构建器中设置值,您需要在基础中使用构造函数来获取参数:
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"};
}
}