2017-09-14 10 views
0

작성을위한 모범 사례 :상속 -의 내가이 수업을 가정 해 봅시다 파생 클래스

class Employee 
{} 

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

지금, 직원이 새 속성 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가 함께 오는 경우 mantain하기 쉬운 응용 프로그램을 가지고 싶습니다.

따라서 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 클래스의 인스턴스를 만들면 걱정이됩니다. 누가 이것을 책임 져야합니까?

하나의 옵션으로 직원이 이에 대해 알게 될 수 있습니다. 즉, 급여 지급 방법을 알고있는 Manager 클래스를 직원에게 알리십시오.

이 경우 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(); 
    } 
} 

또는이 Manager 클래스를 작성해야하는 Factory 클래스가 있어야합니까?

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 클래스에서 발생하면 어떻게 될까요? 다시 말해 Employer 유형에 따라 동작이 다른 세 가지 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); 
    } 
}