Programming/Spring

Spring 기타(1) - 객체 간 결합도가 낮은 이유

코딩하는 포메라니안 2022. 4. 20. 16:07

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);