2017-09-14 53 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); 
    } 
}