ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring][Kotlin] 순수 자바로 객체지향 설계원칙 지키기 + 스프링으로 전환
    Spring 2022. 4. 12. 23:41

    이론적인 내용 위주로 간단히 요약하려고 한다.

     

    프로젝트 생성

    https://start.spring.io 에서

    Project : Gradle Project

    Language : Kotlin

    Spring Boot : 2.6.6

    Packaging : Jar

    이렇게 지정하고 생성하였다.

     

    프로젝트에서 build.gradle.kt 선택하여 프로젝트 연다.

    프로젝트는 Gradle통해서 실행하는 것이 디폴트 설정이다.

    Build Tools에서 Build and run usning, Run tests using 모두 IntelliJ IDEA 바꿔서 실행 속도를 좀 더 빠르게 설정하였다.

     

    회원 도메인 설계가 이렇게 되었다고 하자.

    c.f]

    객체 다이어그램 : 서버가 실제 떠서 어떤 구현체 선택할지의 정보가 담겨있다.(동적인것)
    구현체가 하나만 있을 때는 관례 상 Impl 많이 쓴다.
    위에 MemberService인터페이스의 구현체가 하나밖에 없으므로 MemberServiceImpl을 사용하였다.
    인터페이스와 구현체는 다른 패키지에 넣는 것이 구조 상 좋다.

     

    위를 보면 MemberServiceImpl이 프로퍼티로 MemberRepository 객체를 가지고 있다.

    class MemberServiceImpl : MemberService{
    
    	val memberRepository: MemberRepository = MemoryMemberRepository()
    
    	//생략
    
    
    }

    Problem] 의존관계가 인터페이스 뿐만 아니라 구현까지 의존하는 문제점이 있다.

    Problem2] 구현체를 MemoryMemberRepository에서 JdbcMemberRepository로 변경하는 순간 MemberService도 변경해야 하므로 OCP위반이다.

    이 전 포스팅에서 의존한다는 것은 안다는 것이라고 했다.
    MemberServiceImpl 클래스 안에서 MemoryMemberRepository 객체를 할당해주는 부분이 MemberRepository의 구현체에 의존하고 있다고 볼 수 있다.

    Sol) 누군가 Client(MemberServiceImpl)에 인터페이스 구현 객체를 생성 & 주입해줘야함.

    class AppConfig{
    	
        fun memberRepository() = MemoryMemberRepository()
        
    	fun memberService() = MemberServiceImpl(memberRepository())
        
        //생략
        
    }

     

    class MemberServiceImpl : MemberService{
    
    	val memberRepository: MemberRepository
        
        constructor(memberRepository: MemberRepository){
        	this.memberRepository = memberRepository
        }
        
        //생략
    
    }

     

    그 누군가가 AppConfig이다.

    AppConfig는 구현객체 생성 + 연결 역할을 한다.

    -> 생성자 주입, 의존관계 주입 DI(Dependency Injection)

    AppConfig가 역할을 해줌으로써 Client는 구현 객체에 의존하지 않아도 되었다.

    구현체를 변경해도 AppConfig만 변경하면 된다.

    결과 : DIP, OCP를 잘 지키게 되었다.

     


    AppConfig를 도입함으로써 앱이 사용영역과 구성 영역으로 나뉘었다.

    이로써 클라이언트 객체는 자신의 역할을 실행하는 것에만 집중할 수 있게 되었다.

    -> SRP 단일책임 원칙을 잘 지키게 되었다.

     


    Spring으로 전환하기

    @Configuration : 설정 정보 클래스에 붙여준다.

    @Bean : 해당 메서드에 붙여주면 스프링 컨테이너에 스프링 빈으로 등록한다는 뜻이다.

     

    ApplicationContext

    • 스프링은 모든게 ApplicationContext로 시작된다.
    • 이것을 Spring Container라고 보면 된다.
    • 위의 순수 자바 코드에서는 AppConfig를 통해서 객체를 생성하고 DI 했지만 스프링에서는 스프링 컨테이너를 사용한다.
    • @Configuration 이 붙은 것을 설정 정보로 사용하고 그 안의 @Bean 이 붙은 메서드를 모두 호출해서 반환된 객체를 스프링 컨테이너에 등록한다.
    • 개발자는 이 스프링 컨테이너 통해서 필요한 스프링 빈(객체)를 찾아야 한다.

    Annotation 기반으로 Config하고 있다면

    val applicationContext = AnnotationConfigApplicationContext(AppConfig::class.java)

    ApplicationContext 중 AnnotationConfigApplicationContext를 사용하고 파라미터로 설정정보를 담당하는 클래스를 넣어서 쓰면 된다.

     

    스프링 컨테이너에 등록된 객체를 스프링 빈이라고 한다.
    스프링빈에서는 @Bean이 붙은 메서드 이름을 디폴트 스프링 빈 이름으로 사용한다.

     

     

     

    [출처]

    스프링 핵심 원리 - 기본편

    https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard

     

    스프링 핵심 원리 - 기본편 - 인프런 | 강의

    스프링 입문자가 예제를 만들어가면서 스프링의 핵심 원리를 이해하고, 스프링 기본기를 확실히 다질 수 있습니다., - 강의 소개 | 인프런...

    www.inflearn.com

     

Designed by Tistory.