직전에 마지막에서 다룬 잠재적인 문제점, 즉 Controller 의 code 가 너무 복잡해지는 문제점을 어떻게 해결할 수 있을까?
Purpose of Service Layer

Service Layer 는 Facade Design Patter 을 사용한 전형적인 예시이다.
Facade Pattern 이란, 복잡한 system 이나 subsystem 의 Interface 를 하나의 단순한 고수준의 Interface 로 묶어 system 의 결합도를 낮추고 code 의 가독성과 유지보수성을 높일 수 있는 Design Pattern 이다.
따라서, Controller 는 DAO 와 복잡한 buisness logic 을 알지 못하여도, Service Layer 가 제공하는 단순한 method 만 사용하면 되는 것이다.
또한 Service Layer 는 DAO/repository 등의 data source 들을 integrate 하는데, Controller 내부에서 직접 DAO 를 Injection 받아 사용하는 대신, Service Layer 가 DAO 들을 종합적으로 관리하여 Controller 에서는 단순한 method 만 호출하는 것으로 buisness logic 을 처리할 수 있게끔한다.

정리하면, 위의 이미지에 보는 것처럼, Controller 는 단순히 multiple data sources 들을 integrate 한 Service Later object 하나만 바라보면 된다는 것이다.

Service Layer 로 사용할 class 에는 @Service annotation 을 사용해야 하는데, @Service 는 위와 같이 @Component 의 Specialization 된 annotation 의 형태이다.
따라서 component-scanning 덕분에 Service object 도 Spring Bean 에 등록되어 Spring Container 에 의하여 관리된다.
Implement Employee Service
그럼 이제 Employee Service 를 구현해보자.
Step 1: Define Service Interface
public interface EmployeeService {
List<Employee> findAll();
}Step 2: Define Service Implementation
@Service
public class EmployeeServiceImpl implements EmployeeService {
private EmployeeDAO employeeDAO;
public EmployeeServiceImpl(EmployeeDAO employeeDAO) {
this.employeeDAO = employeeDAO;
}
@Override
public List<Employee> findAll() {
return employeeDAO.findAll();
}
}@Service annotation 을 사용하고, EmployeeDAO 를 Service 에서 injection 받아서 findAll() 이라는 method 를 제공하도록 만든다.
Step 3: Update REST Controller
private EmployeeService employeeService;
public EmployeeRestController(EmployeeService employeeService) {
this.employeeService = employeeService;
}EmployeeDAO 를 declare 하고 injection 하는 대신, EmployeeService 를 declare 하고 injection 하는 방법으로 사용한다. 이렇게 되면 최종적으로 Controller 는 Service 를 바라보게 되고, Service 는 각각의 DAO 를 바로보게 되는 것이다.
이제 requirements 에 대하여 어떤 흐름으로 구현하면 되는지 파악했다. 이제 requirements 의 나머지 부분을 모두 구현하여보자.