객체의 의존 관계에서 강한 결합이란, 어떠한 객체가 다른 객체에 강한 의존성을 가지고 있음을 뜻한다. 예를 들어 A클래스가 B클래스의 참조가 필요하다. 이때 A가 B에 의존하고 있다고 말하고 B를 A의 종속 항목이라고 하다.
예를 들어 슈퍼마리오를 실행할 수 있는 게임기가 있다고 생각해보자.
<GameRunner.java>
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();
}
}
<MarioGame.java>
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");
}
}
GameRunner Class의 멤버 변수 타입으로 MarioGame Class가 존재하는 것을 확인할 수 있다.
여기서 MarioGame이 질려서 다른 게임으로 바꾸고 싶다면 어떻게 해야될까?
MarioGame Class를 다른 종류의 게임 클래스를 변경하면 된다.
<GameRunner.java>
public class GameRunner {
private PacmanGame game;
public GameRunner(PacmanGame game) {
this.game = game;
}
public void run() {
System.out.println("Running Game: " + game);
game.up();
game.down();
game.left();
game.right();
}
}
<PacmanGame.java>
public class PacmanGame{
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");
}
}
하지만 MarioGame이 Class를 다른 종류의 게임 클래스로 바꾸게 되면 GameRunner Class의 코드 대부분이 변경된다.
즉, GameRunner Class가 MarioGame Class에 강하게 의존하게 된다.
이것을 강한 결합(의존성)이 존재한다고 하는 것이다.
느슨한 결합이란 클래스 간 결합력을 약하게 만들었다는 뜻이다.
약한 결합은 구현 클래스를 직접 참조하는 강한 결합과 달리 '추상화'에 의존한다.

<GamingConsole.java>
public interface GamingConsole {
void up();
void down();
void left();
void right();
}
GamingConsole 인터페이스를 만들어 기존의 게임들이 가지고 있던 작업들을 추상 메소드로 선언하고, Game Class들에서 이를 구현하면 되는 것이다.
<MarioGame.java>
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");
}
}
이는 GameRunner Class 내부적으로 코드의 변경이 일어날 필요 없이, 생성자를 통해 객체를 받아 멤버변수에 대입하기만 하면 오브젝트 변경이 가능하다.