Robert.C.Martin 블로그번역 -2 개방/폐쇄 원칙에 대하여(The Open/Closed Principle)

Jooho Son
7 min readOct 15, 2019

--

밥 삼촌의 블로그 포스팅 번역 2탄 입니다.

본문의 대략적인 주제는 개방폐쇄 원칙에 대한 정의 및 일부 반대주장에 대한 반박과
플러그인 아키텍쳐의 소개입니다.

원문 : https://blog.cleancoder.com/unclebob/2014/05/12/TheOpenClosedPrinciple.html

The Open Closed Principle (Robert.C.Martin 2014년 5월 12일 포스팅)

개방 폐쇄 원칙에 관하여

1988년 Bertrand Meyer는 그의 저서인 Object Oriented Software Construction(객체 지향 소프트웨어의 구조)에서 소프트웨어 공학에서
가장 중요한 원칙중 하나인 “개방 폐쇄 원칙”을 아래와 같이 정의했다

“만족스러운 모듈화를 위한 최소한의 조건은 개방성과 폐쇄성을 모두 갖춘 모듈을 만드는 것이다. “
(원문: “A satisfactory modular decomposition technique must satisfy one more requirement: It should yield modules that are both open and closed.”)

  • 모듈의 확장이 가능한 경우에 개방 되어있다고 표현 할 수 있다.
    예를 들어, 모듈이 포함하고 있는 자료 구조에 새로운 필드를 추가하는게 가능하거나,
    모듈이 제공하는 함수들에 새로운 요소를 추가하는 것이 가능해야 한다.
  • 모듈이 다른 모듈에서 사용될 수 있는 경우 폐쇄 되어있다고 표현 할 수 있다.(폐쇄/closed)
    폐쇄성은 모듈이 안정적이고 잘 정의되어 작성됬다고 가정한다(정보 은닉 관점에서의 인터페이스).
    프로그래밍 언어 모듈의 경우 라이브러리에 저장되고 컴파일 될 수 있고, 다른 사람들이 사용 할 수 있는 경우 폐쇄된 모듈이라고 한다.
    모듈에 대한 정의를 내리거나 분할 하는 경우,
    모듈이 닫혔다고 할 수 있는 시점은 프로젝트의 __baseline__ 이라고
    표현되기도 하는 공식 레포지토리(역자:요즘의 git branch로 예를 들자면 QA브랜치정도가 이 부분에 해당하지 않을까 싶다.)에 추가되어 소프트웨어의 한 부분이 되고,
    다른 모듈 설계자들에게 도움이 되는 인터페이스를 제공할 수 있을 때이다.

위와 같은 정의가 구식인 것은 틀림없다.
최근의 많은 언어들은 모듈들이 컴파일 될 필요가 없고, 경영진들이 워터폴 방식을 따라서 모듈의 설계 명세서를 승인하고 제공한다.

그럼에도 불구하고, 이 위대한 원칙의 핵심은 오래된 표현에도 불구하고 빛난다.

이는 곧
“시스템을 변경하지 않고도 시스템의 행위를 확장할 수 있을것이다.”
(원문: “You should be able to extend the behavior of a system without having to modify that system.)
라는 문장으로 표현 될 수 있다.

이 부분에 대해서는 진지하게 생각해볼 필요가 있다.

시스템 내부의 모든 모듈의 행위를 수정 없이 확장 할 수 있다면, 새로운 기능을 추가할 때 그 어떤 오래된 코드(레거시 코드)도 수정하지 않으면서, 새 코드를 작성해서 추가하기만 하면된다.
오래된 코드들이 바뀌지 않으면 다시 컴파일 하지 않아도 되고, 해당 부분들을 재배포 하지 않아도 된다.
단지 새 코드를 새로운 jar, dll 또는 gem 등에 담아서 배포하면 된다.

그리고 이러한 부분들이 jar, dll, gem등이 기능을 분할하는 역할을 한다는 것을 알 수 있게 해준다.

허무맹랑 하게 느껴지는가?
(원문: Is This Absurd)

처음 개방/폐쇄 원칙을 읽으면, 무의미하게 느껴질수있다.
우리들이 쓰고있는 언어들과 설계들은 일반적으로 새로운 기능들이 시스템의 다른 부분들과 분리되어 배포되거나, 컴파일되거나, 작성되는 것을 허용하지 않는다.

거기에 더해서, 현재의 시스템이 변경에 폐쇄되어 있는지, 아직 새로운 기능의 확장에 열려있는지 조차 알기 어렵다.

실제로, 대부분 새로운 기능을 추가할 때 기존 코드 본문 전반에 걸쳐 무수히 많은 변경을 일으킨다.
우리는 Martin Fowler의 저서 리팩토링에서 산탄총수술(Shotgun Surgery)에 대해 쓰기 전부터 이런 부분들이 잘 못 됐다는 것을 알고있지만, 여전히 저질러 버린다.

하지만 우리에겐 이클립스, 인텔리J, 비쥬얼 스튜디오, Vim, Text Mate, Minecraft…..등과 같은 것들이 있다.
이게 무슨 말이지 감을 잡았을거라고 생각한다.
위에서 예를 든 도구들과 같이 변경이나 재배포 없이 손쉽게 확장이 가능한
과할 정도로 많은 도구들이 있다.
우리는 이러한 도구들을 플러그인을 통해서 확장한다.

플러그인 시스템은 개방/폐쇄원칙이 가능하고, 유용하고 매우 강력하다는 것에 대한 긍정적인 증명이라고 볼 수 있다.
플러그인 시스템은 개방/폐쇄원칙의 궁극적인 결론이고, 정점이다.
(원문: “Plugin systems are the ultimate consummation, the apotheosis, of the Open-Closed Principle. They are proof positive that open-closed systems are possible, useful, and immensely powerful.”)

그렇다면 플러그인 시스템들은 어떻게 주요한 비즈니스 룰들을 변경으로부터 폐쇄되고 모든 어플리케이션들이 확장이 가능하도록 관리할 수 있었을까?
단순하게 말하자면, 그들은 개방/폐쇄 원칙을 믿고, 상위 레벨의 규칙들부터 하위 레벨의 디테일 까지 모두 객체 지향 설계의 도구를 사용했기 때문이다.
그들은 매우 세심하게 의존성을 관리하고 잘못된 방향으로 아키텍쳐의 경계를 넘는 것들을 역전시켰다.

그렇기 때문에, 플러그인 아키텍쳐를 설계하는 것은, 플러그인은 시스템에 종속성을 가지고 시스템은 그 어떤 부분도 플러그인에 종속성을 가지지 않게 하는 것이다.

시스템은 플러그인들에 대해서 모르고.
플러그인들은 시스템에 대해서 알고 있다.
(원문: “The system doesn’t know about the plugins. The plugins know about the system.”)

플러그인 아키텍쳐(Plugin Architecture)

Emacs, Vim, Minecraft, 또는 Eclipse등과 같이 플러그인에 기반한 시스템을 만든다면 어떻겠는가?

데이터 베이스에, GUI에 플러그인을 넣을 수 있다면,

새로운 기능을 플러그인 하고 오래된 것들은 때어낼(unplug) 수 있다면,

플러그인들의 정의로 인해 시스템의 행위들이 제어될수 있다면

이러한 것들이 당신에게 얼마나 많은 힘(power)을 주겠는가?

새로운 기능이나, 새로운 사용자 인터페이스, 새로운 디바이스 또는 디바이스의 인터페이스를 추가하고,

SOA(Service Oriented Architecture)적인 부분들을 추가하고 제거하거나, REST를 추가하거나 제거하기가,

Spring, Rails, Hibernate …Oracle 등을 추가하거나 제거하기 얼마나 쉬워지겠는가?

이 정도라면 내가 주장하고자 하는 것을 알 수 있을것이다.

핵심적인 비즈니스 룰들이 플러그인 아키텍처의 핵심에 있다면, 프레임워크, 인터페이스 데이터베이스 또는 특정 기능들의 집합들에 의해 구속될일은 없을 것이다.

결론

나는 개방/폐쇄 원칙이 틀렸다, 유용하지 못하다, 비현실적이다, 진짜 프로그래머들이 진짜 일하는데 쓰지 않는다는 말들을 들어왔다. 하지만 플러그인 아키텍쳐의 성장은 이러한 관점들을 명백하게 말도 안되는 소리들로 만든다.

반대로, 플러그인 아키텍쳐는 앞으로의 소프트웨어 시스템에 있어서 가장 중요한 측면이 될것이다.

--

--

Jooho Son

백엔드 개발자 입니다. 현재는 작고 소중한 스타트업에서 바라는 문화를 만들어 보고자 함께하고 있습니다. Backend Software Developer who works in small startup in South Korea. contact: joohotheman@gmail.com