[ASP.NET Core] 의존성 역전 원칙 예제(DIP)
- 웹 프로그래밍/ASP.NET & ASP.NET Core
- 2022. 4. 14. 21:22
참조
목적
- 의존성 역전 원칙을 보다 쉽게 이해하기 위해서 C# 코드로 예제를 작성하면서 이해합니다.
의존성 역전 원칙을 위반하는 예
- 먼저, 의존성 역전 원칙을 위반하는 예제 코드입니다.
- 2개의 열거형과 하나의 Model 클래스를 만드는 것으로 시작하겠습니다.
public enum Gender
{
Male,
Female
}
public enum Position
{
Administrator,
Manager,
Executive
}
public class Employee
{
public string Name { get; set; }
public Gender Gender { get; set; }
public Position Position { get; set; }
}
- 다음으로 단순히 직원을 추가하는 하나의 하위 수준의 클래스 EmployeeManager 클래스를 생성합니다.
public class EmployeeManager
{
private readonly List<Employee> _employees;
public EmployeeManager()
{
_employees = new List<Employee>();
}
public void AddEmployee(Employee employee)
{
_employees.Add(employee);
}
}
- 또한, 직원에 대한 일종의 통계 분석을 수행하기 위해 더 높은 수준의 EmployeeStatistics 클래스를 생성하였습니다.
public class EmployeeStatistics
{
private readonly EmployeeManager _employeeManager;
public EmployeeStatistics(EmployeeManager employeeManager)
{
_employeeManager = employeeManager;
}
public int CountFemaleManagers()
{
return 1;
}
}
- EmployeeManager 클래스 구조에서는 EmployeeStatistics 클래스의 _employee 목록을 사용할 수 있습니다.
- 따라서 다음과 같이 코드를 추가합니다.
public class EmployeeManager
{
private readonly List<Employee> _employees;
public EmployeeManager()
{
_employees = new List<Employee>();
}
public void AddEmployee(Employee employee)
{
_employees.Add(employee);
}
public List<Employee> Employees => _employees;
}
- 이제 EmployeeStatistics 클래스에서 Count 메서드의 로직을 완료할 수 있습니다.
public class EmployeeStatistics
{
private readonly EmployeeManager _employeeManager;
public EmployeeStatistics(EmployeeManager employeeManager)
{
_employeeManager = employeeManager;
}
public int CountFemaleManagers()
{
return _employeeManager.Employees.Count(emp => emp.Gender == Gender.Female
&& emp.Position == Position.Manager);
}
}
- 위의 코드를 동작하게 되면, 정상적으로 동작은 됩니다.
- 하지만 위 코드는 DIP를 위반한 코드가 됩니다.
- 위 코드가 DIP를 위반한 이유는 다음과 같습니다.
- EmployeeStatistics 클래스는 EmployeeManager 클래스와 강한 결합을 갖고 있으며 EmployeeStatistics 생성자에서 EmployeeManager 객체를 제외하고는 다른 객체를 보낼 수 없습니다.
- 두 번째 문제는 상위 클래스 내부에서 하위 클래스의 공용 속성을 사용하고 있다는 것입니다.
의존성 역전 원칙을 지키는 예
- 앞에서 작성했던 코드를 DIP를 지켜서 리팩토링 해보도록 하겠습니다.
- 먼저 EmployeeManager, EmployeeStatistics 2개의 클래스를 분리하여 두 클래스 모두 추상화에 의존하도록 하겠습니다.
- 따라서 IEmployeeSearchable 인터페이스를 하나 추가하도록 하겠습니다.
public interface IEmployeeSearchable
{
IEnumerable<Employee> GetEmployeesByGenderAndPosition(Gender gender, Position position);
}
- 다음으로 EmployeeManager 클래스를 다음과 같이 수정합니다.
public class EmployeeManager : IEmployeeSearchable
{
private readonly List<Employee> _employees;
public EmployeeManager()
{
_employees = new List<Employee>();
}
public void AddEmployee(Employee employee)
{
_employees.Add(employee);
}
public IEnumerable<Employee> GetEmployeesByGenderAndPosition(Gender gender, Position position)
{
return _employees.Where(emp => emp.Gender == gender && emp.Position == position);
}
}
- 마지막으로 EmployeeStatistics 클래스도 수정합니다.
public class EmployeeStatistics
{
private readonly EmployeeManager _employeeManager;
public EmployeeStatistics(EmployeeManager employeeManager)
{
_employeeManager = employeeManager;
}
public int CountFemaleManagers()
{
return _employeeManager.GetEmployeesByGenderAndPosition(Gender.Female, Position.Manager).Count();
}
}
- 이로써 DIP 규칙을 지키는 코드로 변경되었습니다.
- 이제 EmployeeStatistics 클래스는 하위 수준 클래스에 종속되지 않으며, EmployeeManager 클래스는 Employee 저장에 대한 동작도 변경될 필요가 없습니다.
class Program
{
static void Main(string[] args)
{
var empManager = new EmployeeManager();
empManager.AddEmployee(new Employee { Name = "Leen", Gender = Gender.Female, Position = Position.Manager });
empManager.AddEmployee(new Employee { Name = "Mike", Gender = Gender.Male, Position = Position.Administrator });
var stats = new EmployeeStatistics(empManager);
Console.WriteLine($"Number of female managers in our company is: {stats.CountFemaleManagers()}");
}
}
- 위 처럼 Main 함수를 작성하여 정상적으로 프로그램을 실행할 수 있습니다.
728x90
'웹 프로그래밍 > ASP.NET & ASP.NET Core' 카테고리의 다른 글
[ASP.NET Core] Dependency Injection 예제 (0) | 2022.04.15 |
---|---|
[ASP.NET Core] ASP.NET Core Solution 구조 (0) | 2022.04.15 |
[ASP.NET Core] 의존성 주입(Dependency Injection) 이란? (0) | 2022.04.14 |
[EF Core] ASP.NET Core & EF Core CRUD 구현 (0) | 2022.04.13 |
[EF Core] ASP.NET Core & EF Core(Npgsql & PostgreSQL) (0) | 2022.04.12 |
이 글을 공유하기