본문 바로가기
프로그래밍

개방 폐쇄 원칙 OCP (Open-Closed Principle)

by 탁구치는 개발자 2013. 2. 26.

"클래스나 모듈은 확장에는 열려 있어야 하고 변경에는 닫혀 있어야 한다"


난 위의 OCP 정의를 처음 접했을 때 이해가 되지 않았다.

헌데 토비의 스프링3.1 책을 읽게 되면서 그 의미를 이해하게 됐고, 내가 이해한 것을 토대로 예제 코드를 작성해 보고 싶었다.


아래 예제 코드는 실제 OCP 원칙을 지키지 않은 상태에서의 코드를 보여 줄 것이며 이로 인하여 발생되는 문제에 대해서 설명한다.

그런 후 OCP 원칙을 잘 지키는 코드를 설계하여 개방 폐쇄 원칙이라는 것이 얼마나 코드를 유연하고, 확장성 있게 만드는지 알아볼 것이다.


예제는 컴퓨터와 키보드 이 두 가지를 이용하여 설명할 것이다.

컴퓨터가 부팅을 하면서 키보드를 연결하는 상황이며, 실제 아래와 같이 컴퓨터 소프트웨어를 설계하고 납품을 하게 된다면 어떤 일이 발생하는지 알아보려 한다.


자 컴퓨터 부팅이 시작된다.

public class BootStrap {

public static void main(String[] args) {

Computer computer = new Computer();

computer.boot();

}

}


컴퓨터 부팅을 하면서 S사 키보드 연결을 맺으려 시도한다.

public class Computer {


private final SKeyboard sKeyboard = new SKeyboard();


public void boot() {

System.out.println("부팅 중~~");

sKeyboard.connect();

}

}



S사 키보드가 정상적으로 연결되었다.

public class SKeyboard {


public void connect() {

System.out.println("S사 키보드가 연결 되었습니다.");

}

}


위와 같이 소프트웨어를 개발하고, 컴퓨터를 판매하였다.


사용자들이 컴퓨터를 구매하고, 잘 쓰고 있다가 키보드가 망가져 버리는 상황이 발생했다.

그래서 사용자는 이참에 손가락 건강에 좋고, 슈퍼 울트라 타이핑이 가능한 기계식 키보드를 구매하여 컴퓨터에 연결하였다.

얼라리? 키보드가 동작을 못한다.

사용자는 고객센터에 전화를 걸어 내가 구매한 컴퓨터에 기계식 키보드를 연결했는데 사용할 수 없다라고 문의한다. 허나 돌아오는 답변은 "당사 컴퓨터는 S사 키보드만 연결하여 사용하실 수 있습니다." 라고 한다.


사용자는 멘붕이 오고, 항의한다.


이런 사용자 불만 사항이 빗발치자 컴퓨터 제조사는 아무 키보드나 연결해도 사용 가능한 방법을 모색하게 되었고, 그때 잘생긴 개발자 한 명이 "OCP 원칙을 지키시면 아무 키보드나 연결해서 사용하실 수 있습니다." 라고 한다.


그래서 컴퓨터 제조사는 객체지향적이며 확장성 있고, 유연한 소프트웨어를 개발하게 되었으니...


새로 설계된 소프트웨어가 탑재된 컴퓨터 부팅 start

public class BootStrap {

public static void main(String[] args) {

Computer computer = new Computer();

computer.setKeyboard(new SKeyboard());

computer.boot();

}

}


컴퓨터 부팅을 하면서 키보드를 연결하려고 한다.

public class Computer {


private Keyboard keyboard;


public void setKeyboard(Keyboard keyboard) {

this.keyboard = keyboard;

}


public void boot() {

System.out.println("부팅 중~~");

keyboard.connect();

}

}


이제는 사용자가 어떤 키보드를 연결하여도 사용할 수 있게 되었다.


새로운 소프트웨어는 기존 코드의 어떤 점이 개선되었고, 또한 어떤 장점이 생겼을까?


[첫번 째]

Computer 클래스의 멤버 변수에 Keyboard 인터페이스를 정의하고, setKeyboard 메소드를 통해 특정 제조사의 키보드 객체를 주입 받는다. 

이와 같이 인터페이스를 이용해 키보드 연결이라는 행위를 추상화함으로써 Keyboard 인터페이스를 구현한 어떠한 키보드 클래스도 주입 받을 수 있을 것이다.

즉, S사 키보드를 사용하고 싶을 때나 또는 L사 키보드를 사용하고 싶을 때 Computer 클래스를 수정할 필요 없이 외부에서 키보드 객체를 주입해 주기만 하면 되는 것이다.

결국 이를 통해 OCP 원칙중에 하나인 "변경에는 닫혀있다." 라는 원칙이 성립되는 것이다.


[두번 째]

새롭게 개발된 소프트웨어를 탑재한 컴퓨터는 Keyboard 인터페이스를 구현한 키보드를 언제든지 사용할 수 있는 확장성을 얻게 되었다.

즉, Computer 클래스의 setKeyboard 메소드를 통해 사용하고자 하는 키보드를 주입시켜 다양한 키보드를 사용할 수 있게 된 것이다.

OCP 원칙의 "확장에는 열려있다."를 수용한다.