이 글은 Udemy 사이트에 있는 SpringBoot 강의 기록을 위하여 작성하는 글입니다.
결합이란 코드에서 무엇인가를 변경하는데 얼마나 많은 작업이 관련되어 있는지에 대한 측정
강한 결합 vs 느슨한 결합
• 강한 결합이란?
클래스간에 결합이 많다 혹은 높다고 측정되어서 프로그램내에서 변경사항이 있을때 다량의 코드를 변경해야하는 경우
아래의 코드를 보면 AppGamingBasicJava에서 GameRunner 클래스를 이용하여 MarioGame클래스를 실행 시키고 있다. 이때 GameRunner클래스를 잘 보면 멤버변수로 MarioGame 클래스를 사용하고 생성자의 매개변수 역시 MarioGame 형식의 변수만 받도록 만들어져 있다. 이러한 경우에는 다른 게임으로 실행을 하는 것으로 바꾸고 싶을때 MarioGame 클래스를 사용하는 부분을 모두 다른 게임 클래스를 사용하는 것으로 바꾸어야 한다. 이렇게 코드의 유연선이 떨어지게 만들어진 경우를 강한 결합이라고 한다.
package com.in28minutes.learnspringframework;
import com.in28minutes.learnspringframework.game.GameRunner;
import com.in28minutes.learnspringframework.game.MarioGame;
import com.in28minutes.learnspringframework.game.PacMan;
import com.in28minutes.learnspringframework.game.SuperContraGame;
public class AppGamingBasicJava {
public static void main(String[] args){
var mariogame=new MarioGame();
var gameRunner1 = new GameRunner(mariogame);
gameRunner1.run();
}
}
package com.in28minutes.learnspringframework.game;
public class GameRunner {
private 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();
}
}
package com.in28minutes.learnspringframework.game;
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");
}
}
• 느슨한 결합이란?
클래스간에 결합이 적다 혹은 낮다고 측정되어서 프로그램 내에서 변경사항이 있어도 실행 부분만 변경하는 등 변경량이 적은 경우
느슨한 결합의 경우 강한 결합과 달리 직접적으로 게임 클래스를 사용하는 것이 아닌 인터페이스(interface)의 개념을 도입해서 GameRunner 클래스와 각 게임 클래스간에 인터페이스를 놓는 것이다. 말로만 하면 감이 잘 안 올 수 있으므로 코드를 보자면
package com.in28minutes.learnspringframework;
import com.in28minutes.learnspringframework.game.GameRunner;
import com.in28minutes.learnspringframework.game.MarioGame;
import com.in28minutes.learnspringframework.game.PacMan;
import com.in28minutes.learnspringframework.game.SuperContraGame;
public class AppGamingBasicJava {
public static void main(String[] args){
var mariogame=new MarioGame();
var game=new SuperContraGame();
var pacMan=new PacMan();
var gameRunner = new GameRunner(game);
var gameRunner1 = new GameRunner(mariogame);
var pacRunner= new GameRunner(pacMan);
gameRunner.run();
gameRunner1.run();
pacRunner.run();
}
}
이게 느슨한 결합의 개념을 도입한 AppGamingBasicJava파일인데 강한 결합일때와는 달리 같은 형식의 GameRunner클래스 생성자에 각기 다른 게임의 클래스들이 들어가있다
package com.in28minutes.learnspringframework.game;
public class GameRunner {
private GamingConsole game;
public GameRunner(GamingConsole game){
this.game=game;
}
public void run(){
System.out.println("Running game:"+game);
game.up();
game.down();
game.left();
game.right();
}
}
package com.in28minutes.learnspringframework.game;
public interface GamingConsole {
void up();
void down();
void left();
void right();
}
위에 두 파일을 보면 GameRunner 클래스에서 강한 결합에서 멤버 변수로 게임 클래스를 사용한 것과 달리 GamingConsole이라는 인터페이스를 하나 두어서 해당 인터페이스를 멤버 변수로 사용하고 있다.
package com.in28minutes.learnspringframework.game;
public class SuperContraGame implements GamingConsole {
public void up(){
System.out.println("up");
}
public void down(){
System.out.println("Sit down");
}
public void left(){
System.out.println("Go back");
}
public void right(){
System.out.println("Shoot a bullet");
}
}
package com.in28minutes.learnspringframework.game;
public class MarioGame implements GamingConsole{
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");
}
}
그러고 나서는 각 게임 클래스에서는 GamingConsole 인터페이스를 implements하여 두 클래스가 같은 이름의 메서드를 가지고 있지만 서로 다른 내용을 가지는 형식으로 사용하고 있다는 것을 볼 수 있다.
이렇게 느슨한 결합을 하게되면 인터페이스를 implement 게임 클래스는 GameRunner를 통해 범용성 있게 코드를 활용할 수 있게 되는 것이다. 물론 애초에 생성자 자체를 각 클래스에 맞게(여기서는 각 게임에 맞게) 만들고 위에서 처럼 사용해도 문제 없이 돌아는 간다. 하지만 그렇게 될시에는 GameRunner클래스의 코드 길이가 많이 길어지고 같은 형식의 코드가 반복되기 때문에 그다지 좋은 코드라고는 생각이 되지 않는다. 또한 강한 결합으로 작성한 코드는 기존의 클래스외 새로운 클래스를 추가하는 경우에는 단순히 클래스를 추가하고 실행 파일을 변경하는게 아니라 관계된 파일들을 보면서 필요한 부분을 다 변경해야 하지만 느슨한 결합의 경우 클래스를 추가하면서 실행 파일에 변경만 하면되기 때문에 이러한 변화에 유연하고 효율적으로 대처가 가능하다는 장점이 있다.
'SpringBoot' 카테고리의 다른 글
| [Udemy] Spring Boot 3 - Section 4 : Spring Framework 고급기능 살펴보기 (1) | 2023.11.09 |
|---|---|
| [Udemy] Spring Boot 3 - 의존성 주입 (2) | 2023.11.07 |
| [Udemy] Spring Boot 3 - @Primary VS @Qualifier (1) | 2023.11.02 |
| [Udemy] Spring Boot 3 - Java Bean, POJO, Spring Bean 차이 (6) | 2023.11.01 |
| [Udemy] SpringBoot 3 - Spring Bean (0) | 2023.11.01 |