한 클래스가 다른 클래스에 구체적인 구현체를 직접 생성하고 의존하는 경우를 의미한다.
이 경우 클래스 간의 결합도가 높아져 변경이 어렵고, 확장성이 떨어진다.
(당연히 유지보수가 힘들어짐)
만약 게임의 종류를 바꾸려면 직접 코드를 수정해야한다.
(그럼 컴파일도 다시 해야함)
package com.youjin.spring_practice;
import com.youjin.spring_practice.game.GameRunner;
import com.youjin.spring_practice.game.MarioGame;
public class AppGaming {
public static void main(String[] args) {
var marioGame = new MarioGame();
var gameRunner = new GameRunner(marioGame);
gameRunner.run();
}
}
package com.youjin.spring_practice.game;
public class GameRunner {
MarioGame game;
public GameRunner(MarioGame game) {
this.game = game;
}
public void run(){
System.out.println("Game running: "+ game);
game.up();
game.down();
game.left();
game.right();
}
}
package com.youjin.spring_practice.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");
}
}
-> 특정 게임과 강하게 결합되어있다.
느슨한 결합은 인터페이스를 사용한다.
변경을 최소화하고, 변경이 필요하면 쉽게 변경할 수 있도록 한다.
package com.youjin.spring_practice.game;
public interface Game {
public void up();
public void down();
public void left();
public void right();
}
package com.youjin.spring_practice.game;
public class GameRunner {
Game game;
public GameRunner(Game game) {
this.game = game;
}
public void run(){
System.out.println("Game running: "+ game);
game.up();
game.down();
game.left();
game.right();
}
}
package com.youjin.spring_practice.game;
public class MarioGame implements Game {
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");
}
}
package com.youjin.spring_practice.game;
public class OtherGame implements Game {
public void up(){
System.out.println("up");
}
public void down(){
System.out.println("down");
}
public void left(){
System.out.println("left");
}
public void right(){
System.out.println("right");
}
}
package com.youjin.spring_practice;
import com.youjin.spring_practice.game.Game;
import com.youjin.spring_practice.game.GameRunner;
import com.youjin.spring_practice.game.MarioGame;
import com.youjin.spring_practice.game.OtherGame;
public class AppGaming {
public static void main(String[] args) {
var game = new OtherGame();
var gameRunner = new GameRunner(game);
gameRunner.run();
}
}
-> 이렇게 공통 인터페이스를 만들어서 사용하면, 게임이 바뀔 때마다 GameRunner 클래스를 수정해주지 않아도 된다.
-> 느슨한 결합이다.