继承 - 创建派生类

时间:2017-09-14 11:48:06

标签: c# inheritance factory-pattern

我们说我有这些课程:

class Employee
{}

class SalaryManager
{
    public void PaySalary(Employee e)
    {
        var bankService = GetBankService();
        bankService.Pay(e);
    }
}

现在,Employee有一个新属性PaymentMethod,薪水的支付方式取决于此枚举。

我可以使用ifswitch声明轻松更改付款工资以反映这一点。

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类型而异?这会改变上面的解决方案吗?

1 个答案:

答案 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);
    }
}