포스트

객체지향 설계와 SRP, DIP 원칙에 대해

객체지향 설계와 SRP, DIP 원칙에 대해

four-stages-of-competence four-stages-of-competence 앎의 4단계

내가 어디쯤 와있는지는 모르겠다. 앎의 4단계로 비유하면 의식적 유능 정도의 단계이지 않을까 싶고, 무엇이 좋은 설계인지 조망하는 감은 아직 없다. 그런 와중에 조금씩 알 것 같은 것들이 몇 가지씩 생기고 있다.

객체지향에 대한 단평

객체지향이 고안된 배경이나 객체지향이 잘 하는 것들은 잘 알려져 있다. 종래의 절차지향 패러다임이 지닌 한계를 타파하기 위해서, 세부적으로는 추상적 사고를 보존하고 복잡한 비즈니스 로직을 사람이 이해하기 편한 방식으로 자연스럽게 설계하기 위해서. 그러나 상대적으로 이 방법론이 왜 큰 호응을 얻었는가는 덜 다뤄진다. 그리고 이와 관련해 내가 찾은 관점은 두 개, 사업과 철학이다.

하나. 무언가를 책임진 사업가, 야망가는 불확실성을 싫어하기 마련이다. 국경을 접한 북방 제국이 한반도계 국가를 끊임없이 침략한 이유 중 하나는 대륙 정벌이라는 사업을 달성하기 이전에 후방을 안정시키기 위해서였다. 로마가 카르타고를 치기 전에 이탈리아 반도를 먼저 통일한 사례, 독일은 프랑스 침공 이전에 소련과 불가침조약을 체결한 사례도 동기는 크게 다르지 않다. 사업의 규모가 클수록, 책임자의 집착이 진지할수록 블랙스완 차단은 필수적이다.

둘. 현대물리학자가 대통일 이론을 열망하는 것, 언어학자가 세계의 모든 언어 사이에 보편문법이 있다고 가정하는 것, 경제학자가 수백만 명의 행동을 수요와 공급이라는 하나의 그래프로 설명하려 하는 것 등은 모두 난잡함을 통제해내려는 의도에서다. 왜 그런 노력이 역사적으로 동반되어 왔을까, 그 이면에 인지비용을 낮추려는 실용적인 이유도 있겠지만 나는 알베르 카뮈가 제시한 관점을 더 좋아한다. 예컨대 “인간은 불확실성과 모호함을 견디지 못하고 명료한 인식관을 갈구하기 마련이다”라는 것.

이건 일개 상상일 뿐이다. 하지만 직관으로는 이 두 원리, 위험 관리 기질과 인간 본성이 프로그래밍에서 작용한 결과로서 객체지향을 이해하더라도 큰 위화감은 없어 보인다. 객체지향은 전통적 절차지향 코드를 나누어 적재적소에 정리하고 그 구조와 이름에 더 많은 이정표를 남기면서, 결과적으로 불확실성을 감소시키고 복잡도를 통제하며 개발자에게 안정감을 선사한다.

SRP: 단일 책임 원칙

객체는 각각 하나만의 책임을 갖는다.

비슷하게 글쓰기에는 한 개의 문장에서는 한 가지의 주제만을 다루라는 일문일사一文一事 원칙이 있다. 그래서 단일 책임 원칙의 취지 자체는 낯설지 않고 자칫 오해해버리기 쉽다. ‘관심사를 쳐내어 의미상 명료함을 달성하는 것’, 이것은 SRP의 주된 요지이기는 하지만 핵심은 아니다. SRP가 진정으로 도달하고자 하는 것은 해석가능성을 한 개로 통제하는 것이고, 그리하여 변경의 예측가능성을 달성하는 것이다.

SOLID 원칙은 살아 숨쉬는 프로그램을 전제로 만들어졌다. 상황은 계속 바뀔 것이고 프로그램도 계속 바뀌어야만 한다. 이때 필요한 것은 손자병법의 태도, 철저한 계산으로 리스크를 관리하고 효율을 달성하고자 하는 셈법이다. 유능한 장수는 병사를 두 번 징집하지 않고 군량을 세 번 수송하지 않는다役不再籍, 糧不三載는 말마따나 반복 비용을 소거하는 것은 중요하다.

같은 이유로 개발 단계에서 작업 목표를 명확히 인식하는 것과 작업량을 최소화하는 것, 부작용 없이 과감히 실행할 수 있는 것과 그렇지 않은 것에는 큰 비용 차이가 있다. 이 맥락에서 의미관계가 명확하다는 것은 곧 행동의 파급력이 예측 가능하다는 것이고, 이는 다시 곧 행동 리스크를 계산할 수 있다는 것이 된다. SRP를 진작 수용해 놓아야 하는 이유다.

DIP: 의존성 역전 원칙

추상이 세부사항에 의존하는 게 아니라, 세부사항이 추상에 의존해야 한다.

나는 대체병역으로 사회복무를 이행하면서 회사의 자정능력이 어디까지 관철되는지를 바라볼 수 있었고, 재밌게도 그 과정에서 DIP 원칙을 계속 떠올렸다. 발상은 이렇다. 부서와 그 구성인원간 업무분장이 있는 전형적인 회사 구조에서 DIP에 따르면 회사는 사회적으로 먼저 합의된 개념, 업무분장에 대해서만 의존해야지 그 업무를 수행하는 직원의 개인기나 기량에 의존해서는 안 된다.

사실 당연한 것일지 모른다. 회사의 나날은 고정된 것처럼 보이고 어제도 오늘도 내일도 그 직원이 그 자리에서 같은 업무를 수행할 것처럼 느껴지기 마련이다. 하지만 현실적으로 정기적 발령이나 급격한 인사이동, 퇴사, 극단적으로는 버스 팩터Bus Factor에서의 끔찍한 가정처럼 업무 담당자가 사망하는 등의 이유로 직원이 교체되는 일은 일어날 수밖에 없다. 만약 조직이 업무분장을 넘어 개개인의 역량에까지 의존하고 있었다면 어떠한 이유로든 그 사람이 부재하게 되었을 때 혼선이 빚어지게 된다.

이 관점에서 한 사람에게 합의된 범주를 넘어선 업무가 위임되는 상황을 막아야 하는 이유는 그것이 한 사람의 선의를 이용하는 비도덕적인 행위여서이기 이전에 조직이 와해되는 위험을 야기할 수 있기 때문이다. 한 번은 괜찮을지도 모르나 여러 번은 안 된다. 예를 들어 조직에 요구되는 업무량이 늘어났다면 개개인에게 업무를 과중시킬 것이 아니라 업무분장을 손봐서라도 책임이 분배되는 구조에 대해 재합의를 이뤄야 한다. 그리고 이 감각을 기술적으로 번역하면 원문이 된다. ‘추상이 세부사항에 의존하는 게 아니라, 세부사항이 추상에 의존해야 한다’

형해화

실리에 의해 제시된 개념이 하나의 규범으로 자리잡으면서 의미는 사라지고 형식만 덩그러니 남아버리게 되는 경우가 있다. 사실 그런 경우가 있다 정도가 아니고 우리가 아는 대다수의 것들이 그렇게 자리잡아 문화와 전통이 된다. OOP도 실리에 가치를 둔 방법론으로 출발했으나 오늘날 프로그래밍 커리큘럼에 있어서 하나의 통과의례처럼 여겨지는 경향은 있는 것 같다.

이미 성능에 있어서는 DOD라는 훌륭한 접근이 있고, 상태 관리의 복잡성에 있어서는 함수형 패러다임이라는 대안이 있다. 특히 최근에는 바이브 코딩이 새 트렌드로 떠오르면서 코드 설계를 사람이 직접 들여다보지 않는 방향으로 발전하고 있기 때문에, 객체지향 설계가 앞으로도 꾸준히 선택될 수 있을지 의심되는 면도 있다. 어떤 패러다임이든 오래오래 경직된 전통으로 남는 일은 없기를 바란다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.