2017-09-14 43 views
0

比方说,我有这些类的最佳做法:传承 - 用于创建派生类

class Employee 
{} 

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

现在,员工有一个新的属性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(); 
    } 
} 

或者我应该有一个工厂类,负责或创建此经理类?某些内容如下:

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类中,该怎么办?换句话说,有三种不同的经理类(每个负责自己的事情 - 即TaxCalculationManager),其行为因员工类型而异?这会改变上面的解决方案吗?

+0

这个问题听起来太广,坦率地说,它听起来就像你已经知道答案(接口)。 – buffjape

+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); 
    } 
}