강한 결합과 느슨한 결합

MMM·2024년 3월 22일

강한 결합

여기 세 클래스가 있다.

1) 이름만 마리오 게임인 MarioGame

public class MarioGame {

    public void up() {
        System.out.println("Jump");
    }

    public void down() {
        System.out.println("Go into a hole");
    }

    public void left() {
        System.out.println("Go back");
    }

    public void right() {
        System.out.println("Accelerate");
    }

}

2) 게임을 실행해 줄 GameRunner

public class GameRunner {

    MarioGame game;

    public GameRunner(MarioGame game) {
        this.game = game;
    }

    public void run() {
        System.out.println("Running game: " + game);
        game.up();
        game.down();
        game.left();
        game.right();
    }
}

3) GameRunner를 실행할 AppGamingBasicJava 클래스다.

public class AppGamingBasicJava {

    public static void main(String[] args) {
        MarioGame game = new MarioGame();
        GameRunner gameRunner = new GameRunner(game);
        gameRunner.run();
    }

}

이 때도 코드는 이상 없이 잘 동작한다. 다만 문제는 MarioGame 외 다른 게임을 실행하고 싶을 때. SuperContraGame이라는 게임을 추가하려면 GameRunner에 새로운 생성자를 추가하던가 하는 방식으로 수정을 해줘야한다. 한두개는 괜찮겠지만 50개, 100개가 된다면? 노가다를 좋아해도 귀찮아질 수밖에 없다. 이래서 가능한 한 코드는 느슨한 결합을 가지는 게 좋다. 변화가 생기더라도 최대한 코드를 적게 수정할 수 있기 때문이다.

느슨한 결합

인터페이스


내가 만들고자 하는 MarioGame, SuperContraGame, PacManGame은 모두 동일하게 up, down, right, left 네 개의 메소드를 가지고 있다. 해당 동작을 할 때 출력되는 글귀만 다를 뿐이다. 이럴 때 활용할 수 있는 게 인터페이스다. GameRunner와 각 게임 사이에 GamingConsole이라는 인터페이스를 끼워넣어주면, 새로운 게임을 몇 개 만들든 다른 코드를 수정할 필요 없이 동작하게 할 수 있다. GameRunnerGamingConsole과 결합되어 있을 뿐이기 때문이다.

인터페이스를 통한 느슨한 결합

public class AppGamingBasicJava {

    public static void main(String[] args) {
//        MarioGame game = new MarioGame();
//        SuperContraGame game = new SuperContraGame();
        PacmanGame game = new PacmanGame(); // (1)
        GameRunner gameRunner = new GameRunner(game);  // (2)
        gameRunner.run();
    }

}

위 코드에서 (1) PacmanGame 객체를 생성하고, (2) GameRunner 객체를 생성하는 동시에 의존성을 주입(Wiring of Dependencies)하고 있다. GameRunner는 실행할 때 반드시 game이 필요하다. 따라서 game(GamingConsole, MarioGame, ...)이 GameRunner 클래스의 의존성이다.(Game is a Dependency of GameRunner) game의 클래스는 생성되고 GameRunner에 주입되거나 결합된다.


프로젝트 규모가 커지면 수천 개의 의존성이 생성되고 주입된다. 현재는 객체가 JVM에서 생성되고, 객체를 생성하고 결합하는 코드는 개발자가 직접 작성하고 있다. 그러나 스프링 프레임워크가 대신 객체를 생성하고 결합할 수 있다.

profile
과거의 내가 현재의 나보다 똑똑할 때가 있다.

0개의 댓글