Dependency(의존관계)란?

의존관계는

  • 코드에서 두 모듈간의 연결을 의존관계라 합니다.
  • 객체지향언어에서 두 클래스 간의 관계를 말하기도 합니다.

 

의존관계의 종류는 크게 4가지가 존재합니다.

  1. Dependency(의존관계)
  2. Association(연관관계)
  3. Aggregation(집합관계)
  4. Composition(합성관계)

보통 4가지를 통틀어 Dependency라고 뭉뚱그려 부르긴 하지만 각각의 차이를 인지하는 것이 중요합니다. 

 

이제부터 하나씩 알아보겠습니다.

Dependency(의존관계)

public class UserService {

    public void saveUser(UserRepository userRepository){
        System.out.println("유저저장");
        userRepository.save();
    }

}


public class UserRepository {

    public void save(){
        // do something ..
    }

}

의존관계란 클래스가 다른 클래스를 일시적으로 참조하는 형태입니다.

이 코드에서는 Service가 User를 저장할 때 UserRepository를 param으로 불러와 사용합니다.

saveUser 연산을 동작시킬때만 일시적으로 참조하게 되며 생명주기와 같은 어떤것도 일치하지 않습니다.

가장 낮은 수준의 결합도를 가집니다.

 

Association(연관관계)

public class UserService {
    private UserRepository userRepository;

    public UserRepository getUserRepository() {
        return userRepository;
    }

    public void saveUser() {
        this.userRepository = new UserRepository();
        System.out.println("유저저장");
        userRepository.save();
    }

}


public class UserRepository {

    public void save(){
        // do something ..
    }

}

UserService 객체를 생성할 때는 UserRepository가 생성돼있지 않습니다.
이 부분은 의존관계와 동일하지만 saveUser() 메서드를 호출 해 동작이 끝났음에도 Repository 객체가 남아있게 됩니다.

 

public class Main {

    public static void main(String[] args) {

        UserService userService = new UserService();

        System.out.println(userService.getUserRepository());

        userService.saveUser();

        System.out.println(userService.getUserRepository());

    }

}


이것이 의존관계와의 차이점이며 의존관계보다 높은 결합도를 가집니다.

 

Aggregation(집합관계)

public class UserService {
    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public UserRepository getUserRepository() {
        return userRepository;
    }

    public void saveUser() {
        System.out.println("유저저장");
        userRepository.save();
    }

}

public class UserRepository {
    public void save() {
        // do something ..
    }

}

생성자를 통해 다른 클래스의 객체를 받아오는 경우입니다.

(Field를 Final로 선언할 수 있다는 장점이 있습니다.)

UserService 생성을 위해서 필수적으로 UserRepo가 필요합니다.

하지만 이것이 UserService와 UserRepository가 동일한 생명주기를 가진다는 건 아닙니다.

 

UserRepository가 먼저 생성되고 사용된 후 Service 생성도 가능하기 때문입니다.

public class Main {

    public static void main(String[] args) {

        UserRepository userRepository = new UserRepository();

        userRepository.save();
        userRepository.save();
        userRepository.save();

        UserService userService = new UserService(userRepository);
        System.out.println(userService.getUserRepository());
        userService.saveUser();
    }

}

 


기존 관계들과의 차이점은 메서드 호출없이 객체 생성만해도 Repository가 존재합니다.

 

Composition(합성관계)

public class UserService {
    private final UserRepository userRepository;

    public UserService() {
        this.userRepository = new UserRepository();
    }

    public UserRepository getUserRepository() {
        return userRepository;
    }

    public void saveUser() {
        System.out.println("유저저장");
        userRepository.save();
    }

}

public class UserRepository {
    public void save() {
        // do something ..
    }

}

UserService와 UserRepository의 생명주기가 완전히 일치하게 됩니다.
이런 형태를 강하게 결합한다 라고도 말합니다.

 

코드의 결합이 강해지게되면 재사용성이 크게 떨어지기 때문에 보통 Aggregation 관계를 사용합니다.

 

IoC/DI와 Dependency의 관계

 

IoC는 프로그램이 흐름의 제어권을 갖음을 말합니다.

Spring에 경우 Context에 Bean을 등록하고 관리하는 등 Spring Bean의 생명주기를 스스로 관리합니다.

그런데 Aggregation , Composition 과 같이 객체 생성을 위해서 다른 클래스를 필요로하는 경우는 어떡할까요??

 

public interface Language {
    // do something
}

public class Korean implements Language{
    // do something
}

public class English implements Language{
    // do something
}

public class LanguageService {

    private final Language language;

    public LanguageService(Language language) {
        this.language = language;
    }
}

LanguageService는 Aggregation 의존관계를 갖습니다.

따라서 자체적인 객체생성이 불가능하며 다른 타입의 객체가 필요합니다.

하지만 Type이 Language로 되어있기 떄문에 필요한 객체의 타입은 English가 될 수도 Korean이 될 수도 있습니다.

따라서 프로그램이 무엇을 의존할지 자체적으로 정할 수 없게되고

어떤 타입의 객체를 사용할 것인지를 외부에서 주입해줘야 합니다.
(Korean,English 또한 설정을 추가해 주입해줘야 함)

 

이를위한 여러가지 의존관계 주입방법이 나오게됐으며 이를 통틀어 Dependency Injection 이라 부릅니다.

 

아래는 같이읽어보면 좋은 글입니다. 

https://masiljangajji-coding.tistory.com/51

 

IoC(Inversion Of Control)란

IoC/DI(Inversion Of Control/Dependency Injection)란 IoC(Inversion Of Control)란? IoC는 제어의 역전을 뜻합니다. 제어의 역전.. 제어가 역전된다.. 이게 어떤 의미일까요? 기존의 프로그램은 구현 객체가 프로그램

masiljangajji-coding.tistory.com

 

https://masiljangajji-coding.tistory.com/53

 

Dependency Injection(의존관계 주입)이란

Dependency Injection(의존관계 주입)이란? 이 글은 IoC , Dependency 의 개념을 알고있다는 전제하에 작성된 글입니다. 원활한 이해를 위해서 아래글을 읽어주세요 https://masiljangajji-coding.tistory.com/51 IoC(Inver

masiljangajji-coding.tistory.com

도움이 되셨으면 좋겠습니다.

'Spring > Spring Core' 카테고리의 다른 글

Dependency Injection(의존관계 주입)이란  (3) 2024.01.04
IoC(Inversion Of Control)란  (1) 2024.01.02

+ Recent posts