Spring은 IoC를 통해, 객체 간의 결합도를 낮출 수 있다고 한다. 이번 글에서는 그 이유를 더 자세하게 살펴보려고 한다. 객체의 강한 결합부터 Spring에서 사용하는 약한 결합까지 차례로 작성했다.
1. 객체 간 강한 결합
클래스를 직접 호출
한계
결합된 클래스(UserServiceImpl, AdminServiceImpl)가 수정되면, HomeController도 수정해야 한다.
public class HomeController{
private UserServiceImpl userService = new UserServiceImpl();
private AdminServiceImpl adminService = new AdminServiceImpl();
public void addUser(User user){
userService.join(user);
adminService.register(user);
}
}
2. 객체간 결합 낮추기
1. 인터페이스 호출 방식
두 클래스가 하나의 인터페이스를 구현하고 있으므로, MemberService라는 인터페이스 하나에 다양한 객체를 담을 수 있다. 즉, 교체가 쉽다는 것이다.
한계
인터페이스가 수정되면, HomeController도 수정해야 한다.
public class HomeController{
private MemberService userService = new UserServiceImpl();
private MemberService adminService = new AdminServiceImpl();
public void addUser(User user){
userService.register(user);
adminService.register(user);
}
}
2. Factory 사용하기
Factory클래스를 만들어서, 객체를 받아와서 쓰자. 인터페이스 이름만 알면 가져와서 쓸 수 있다. 구현체(___Impl)와의 완전한 독립으로 볼 수 있다.
Spring의 Container에는 Factory 패턴이 적용되기 때문에, 객체를 사용할 때 직접 구현체를 생성하지 않고 Container에서 받아와서 사용한다. 자세한 코드는 아래에 [3. Assembler 사용하기]의 [2) 사용하기]에서 확인할 수 있다.
한계
Factory를 사용하기 위해서는 Factory를 호출하는 코드가 들어가므로 여전히 의존적이다.
public class HomeController{
private MemberService userService = MyFactory.getUserService();
private MemberService adminService = MyFactory.getAdminService();
public void addUser(User user){
userService.register(user);
adminService.register(user);
}
}
public class MyFactory{
public static MemberService getUserService(){
return new UserServiceImpl();
}
public static MemberService getAdminService(){
return new AdminServiceImpl();
}
}
3. (Spring) Assembler 사용하기
Runtime(실행 시점)에 클래스 간의 관계가 형성되도록 하기 때문에, 클래스들은 코드 상으로 독립적인 관계가 된다. 다시 말해, 설정 파일에 관계를 다 작성해놓고 실행시키면 Spring이 알아서 조립하여 실행시킨다.
1) 설정 파일(이름은 주로, application.xml로 만들어 사용)에 Container가 객체 관리하도록 등록하기
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<bean id="user" class="com.test.hello.service.UserServiceImpl"></bean>
<bean id="admin" class="com.test.hello.service.AdminServiceImpl"></bean>
</beans>
2) 사용하기
Spring의 Container 객체를 만들면서 설정파일을 넘겨줬다. 이를 바탕으로 만들어진 Container는 Factory 구조로 구성되어 있으므로 getBean을 이용하여 객체를 받아와서 사용할 수 있다.
ApplicationContext context = new ClassPathXmlApplicationContext("com/test/hello/service/application.xml");
MemberService userService = context.getBean("user", MemberService.class);//id=user인 클래스를 받아 MemberService로 형변환
MemberService adminService = context.getBean("admin", MemberService.class);
'Programming > Spring' 카테고리의 다른 글
Spring (3) - Container에 객체(Bean) 설정하기3 : Annotation (0) | 2022.04.23 |
---|---|
Spring (3) - Container에 객체(Bean) 설정하기2 : XML (0) | 2022.04.22 |
Spring (3) - Container에 객체(Bean) 설정하기1 : 프로젝트 생성 (0) | 2022.04.22 |
Spring (2) - IoC와 Container (0) | 2022.04.20 |
Spring (1) - Spring Framework란? (0) | 2022.04.15 |