관리 메뉴

KorSA

소프트웨어는 살아 숨쉬는 생태계이다! (feat. 객체 지향의 사실과 오해 - 조영호) 본문

Books/Software Developments

소프트웨어는 살아 숨쉬는 생태계이다! (feat. 객체 지향의 사실과 오해 - 조영호)

Praiv. 2022. 2. 2. 09:18
320x100

객체지향의 사실과 오해

 

# 설계가 중요해?

프로그래밍에 있어 기능 하나를 위해 코드를 짜는 건 어느정도 문법만 뗀 사람이면 가능하다.

하지만 기능을 짤 수 있다는 사실 자체가 곧 좋은 소프트웨어를 만든다는 의미는 아니다.

 

소프트웨어는 수 많은 객체들이 살아가고 동적으로 상호작용하는 하나의 생태계이다. 이 생태계가 잘 유지되고 매일 매일을 살아가기 위해서는 이 공동체를 떠받들고 있는 근본 구조가 잘 지지해주어야 한다. 이를 프로그래밍의 세계에서는 ‘설계’라고 부른다. 기능을 잘 만드는 개발자라고 해서 반드시 설계를 잘한다고는 말할 수 없다. 애초에 요구하는 역량 자체가 다르고 소프트웨어 개발에 있어 소속되어 있는 범주도 다르기 때문이다.

 

 

# 소프트웨어 설계의 관점 3가지

객체지향 설계에는 크게 개념 관점(Conceptual Perspective), 명세 관점(Specification Perspective), 구현 관점(Implementation Perspective) 의 3 가지 관점이 있다.

 

‘개념 관점’에서 설계는 도메인 안에 존재하는 개념과 개념들 사이의 관계를 표현한다. 여기서 말하는 도메인이란 프로그램이 사용될 분야에서 사람들 사이에 통용되는 지식들이다. 예를 들어 은행 업무에서는 일반적으로 고객이 은행원에게 찾아가 통장 개설 혹은 해지를 요청한다. 여기서 ‘고객’, ‘은행원’, ‘통장’ 등의 객체에 대한 개념과 ‘통장 개설을 요청한다’, ‘통장 해지를 요청한다’ 등의 행위에 대한 개념은 은행 업계 사람들 사이에서 상식으로 통하는 내용들이다. 이를 도메인 모델 혹은 멘탈 모델이라고 한다. ‘개념 관점에서의 설계’는 이러한 도메인 모델을 바탕으로 프로그램의 전반적인 설계를 하기 때문에 사용자의 관점이 녹아들어 있다.

 

‘명세 관점’에서 설계는 사용자의 영역인 도메인에서 벗어나 개발자의 영역인 소프트웨어로 초점이 옮겨진다. 이 지점에서 ‘인터페이스’에 대한 설계를 진행한다. 인터페이스는 어떤 두 사물이 마주치는 경계 지점에서 서로 상호작용할 수 있게 이어주는 방법이나 장치를 의미한다. 예를 들어 자동차 운전자는 자동차의 내부 구조가 어떻게 구현되어있는지 모르더라도 자동차를 운전할 수 있는데, 이는 자동차를 만드는 사람이 일반 사람들도 사용 가능하도록 운전대, 페달, 계기판 등의 인터페이스를 만들어두었기 때문이다. 또한 이 인터페이스 덕분에 운전자는 자신의 차 뿐만 아니라 (같은 인터페이스를 지닌) 다른 자동차도 운전할 수 있고 자동차 내부가 수리나 업그레이드로 변경되었다 하더라도 운전자는 신경쓸 필요가 없다. 인터페이스 설계는 객체가 협력을 위해 ‘무엇’을 할 수 있는가에 초점을 맞춘다.  이 단계에서는 소프트웨어 안에서 살아 숨쉬는 객체들의 책임에 초점을 맞춘다. 아직 ‘어떻게’에 대해 설계하는 단계가 아님에 주의할 필요가 있다. 훌륭한 객체지향 설계의 가장 기본 원칙은 인터페이스와 구현의 분리, 즉 ‘무엇’과 ‘어떻게’를 분리하는 것이기 때문이다. 이 두 영역의 분리가 제대로 이루어지지 않을 경우, 자동차 운전자는 운전을 하고자 할 때마다 자신이 페달을 밟음으로써 자동차가 어떻게 동작하는지를 매번 신경써야하는 사태가 초래되고 아마 그 운전자는 운전을 포기할지도 모른다.

 

‘구현 관점’은 프로그래머인 우리에게 가장 익숙한 관점으로 실제 작업을 수행하는 코드와 연관돼 있다. 구현 관점의 초점은 객체들이 책임을 수행하는 데 필요한 동작하는 코드를 작성하는 것이다. 여기서 객체가 자신의 책임을 ‘어떻게’ 수행할 것인가를 기술하게 된다. 이 글의 도입부에서 말한 기능을 짜는 단계는 이 부분이다. 

 

 

# 근데 소프트웨어가 뭐길래?

 

객체지향 설계의 대상이 되는 소프트웨어에 대해 좀 더 알아보자.

 

소프트웨어는 객체들이 역동적으로 살아 숨쉬는 하나의 공동체이자 생태계이다.

 

흔히 객체지향을 이야기할 때 클래스에 중점을 많이 두는데, 사실 그보다 더 중요하고 핵심적인 것은 객체이지 클래스가 아니다. 자바스크립트 등의 언어는 애초에 클래스 자체가 없기 때문이다. 클래스는 단지 객체의 속성과 행동을 기술하기 위한 방법들 중 하나일 뿐이다.

 

객체들은 각자가 자신의 ‘역할’‘책임’을 지니고 있다. 그리고 이 역할과 책임을 바탕으로 다른 객체들과 ‘협력’한다. 앞서 예를 든 은행업무에서 은행원의 역할은 고객의 요청을 받는 것이다. 은행원의 책임은 자신이 받은 요청에 적절한 응대를 하는 것이다. 은행원의 협력은 고객과의 대화이다.

 

소프트웨어의 세계에서 협력은 ‘메시지’의 형태로 나타난다. 메시지는 메시지의 목적을 나타내는 ‘메시지 이름(message name)’과 메시지의 추가 정보를 나타내는 ‘인자(arguments)’로 구성되어 있다.

 

 

# 그렇다면 좋은 설계란?

 

첫번째로 앞서 말한대로 인터페이스(무엇)와 구현(어떻게)이 분리되어 있어야 한다. 이 둘이 서로 얽혀서 나뒹구는 순간 인간의 뇌는 그 복잡성을 따라가지 못한다. 개발자가 매번 개별 기능의 구현에 신경써야 할 경우 기능이 3개일 때보다 10개일 때 고려해야 할 경우의 수가 (선형적이 아닌) 지수함수적으로 증가한다.

 

두번째로 변화에 유연해야 한다. 불행하게도 우리 같은 선량한 개발자들이 개발 초기에 받았던 요구사항은 변경될 것이다. 소프트웨어 분야에서 예외가 없는 유일한 규칙은 요구사항이 항상 변경된다는 것이다. 설계라는 행위를 중요하게 만드는 것은 변경에 대한 필요성이다. 안타깝게도 변경을 피할 수 있는 방법이 없기 때문에 좋은 설계에 대한 압력 역시 피할 수 없다.

 

또한 설계가 어려운 이유는 어제 약속했던 기능을 제공하는 동시에 내일 변경될지도 모르는 요구사항도 수용할 수 있는 코드를 창조해야 하기 때문이다. 요구사항을 만족시킬 수 있는 다양한 설계안들을 저울질하면서 그 결과로 단순하면서도 유연한 설계를 창조하는 것은 공학이라기보다는 예술에 가깝다. 개발자들은 미래의 변경에 대비할 수 는 있지만 미래의 변경을 예측할 수는 없다. 미래에 대비하는 가장 좋은 방법은 변경을 예측하는 것이 아니라 변경을 수용할 수 있는 선택의 여지를 설계에 마련해 놓는 것이다.

 

 

# 그냥 내 생각

 

현업에서 일을 하다보면 이론적으로 응당 그래야한다고 생각했던 것들에 많은 타협을 보게 되는 순간이 많다. 바쁜 일정, 급한 이슈 등 어쩔 수 없다는 생각을 많이 했지만 요즘 들어서는 이러한 '어쩔 수 없다'를 줄이는 게 진짜 실력이 아닌가 싶다.

 

설계가 잘 되어 있으면 바쁜 일정에서도 유연하고 효율적으로 (그리고 무엇보다도 빠르게!) 대응할 수 있다. 급한 bug fix가 오더라도 설계에 따른 격리 원칙이 잘 적용되어 있다면 bug의 범위를 신속히 제한할 수 있다.

 

이러한 환경을 갖추려면 스스로도 노력해야 하고 팀 전체에게 이런 문화가 유지되게끔 노력하는 것도 필요하다. 그렇게 되면 어느새 인문학에 발을 담그게 되고 그렇게 되고 그렇게 되면... 역시 끝이 없는 게 세상이구나.

 

 

 

 

 

728x90
728x90
Comments