我们说我有这些课程:
class Employee
{}
class SalaryManager
{
public void PaySalary(Employee e)
{
var bankService = GetBankService();
bankService.Pay(e);
}
}
现在,Employee有一个新属性PaymentMethod
,薪水的支付方式取决于此枚举。
我可以使用if
或switch
声明轻松更改付款工资以反映这一点。
class Employee
{
public enum PaymentMethod { get; set; }
}
class SalaryManager
{
public void PaySalary(Employee e)
{
if (e.PaymentMethod == Cash)
{
var bankService = GetBankService();
bankService.Pay(e);
}
else if (e.PaymentMethod == Online)
{
// Different implementation
}
}
}
当然,我希望有一个更容易保护的应用程序,以防新的PaymentMethods出现。
因此,我可以将SalaryManager作为基类(或接口)并具有两种不同的特化。
class SalaryManager
{
public abstract void PaySalary(Employee e);
}
class CashSalaryManager : SalaryManager
{
public override void PaySalary(Employee e)
{
var bankService = GetBankService();
bankService.Pay(e);
}
}
class OnlineSalaryManager : SalaryManager
{
public override void PaySalary(Employee e)
{
// Different implementation
}
}
我关心的是创建这个SalaryManager类的实例。谁应该对此负责?
一个选项可能是让员工了解这一点。换句话说,让员工知道哪个应该是知道如何支付薪水的经理类。
在这种情况下,我是否应该为Employee提供两个不同的派生类?
class Employee
{
public enum PaymentMethod { get; set; }
public abstract SalaryManager GetSalaryManager();
}
class CashEmployee
{
public override SalaryManager GetSalaryManager()
{
return new CashSalaryManager();
}
}
class OnlineEmployee
{
public override SalaryManager GetSalaryManager()
{
return new OnlineSalaryManager();
}
}
或者我应该有一个负责的Factory类或者创建这个Manager类?有些东西:
static class SalaryFactory
{
public static SalaryManager CreateSalaryManager(Employee e)
{
SalaryManager manager = null;
if (e.PaymentMethod == Cash)
{
manager = new CashSalaryManager();
}
else if (e.PaymentMethod == Online)
{
manager = new OnlineSalaryManager();
}
else
{
thrown new Exception ("No Manager class found for the payment type");
}
}
}
如果在不同的Manager类中发生这种情况怎么办?换句话说,有三个不同的Manager类(每个类都负责自己的东西 - 即TaxCalculationManager),其行为因Employee类型而异?这会改变上面的解决方案吗?
答案 0 :(得分:0)
我会按照这个和控件容器的用户反转来做一些事情,将所有ISalaryManager实现注入SalaryPaymentManager。然后,您需要做的就是为每种付款类型制作新的ISalaryManager实现
public class Employee
{
}
public interface ISalaryManager
{
void PaySalary(Employee e);
bool HandlesPaymentType(string paymentType);
}
public class CashSalaryManager : ISalaryManager
{
public void PaySalary(Employee e)
{
var bankService = GetBankService();
bankService.Pay(e);
}
public bool HandlesPaymentType(string paymentType)
{
return paymentType == "Cash";
}
}
public class OnlineSalaryManager : ISalaryManager
{
public void PaySalary(Employee e)
{
// Different implementation
}
public bool HandlesPaymentType(string paymentType)
{
return paymentType == "Online";
}
}
public class SalaryPaymentManager
{
private readonly IEnumerable<ISalaryManager> _salaryManagers;
public SalaryPaymentManager(IEnumerable<ISalaryManager> salaryManagers)
{
_salaryManagers = salaryManagers;
}
public void PaySalary(string paymentType, Employee employee)
{
var salaryManager = _salaryManagers.FirstOrDefault(x => x.HandlesPaymentType(paymentType));
if (salaryManager == null)
throw new NotImplementedException();
salaryManager.PaySalary(employee);
}
}