쓸모 있는 모듈러 디자인
모듈화의 원리, 모듈러 디자인의 방법론에는 기구, 하드웨어, 소프트웨어 영역을 가릴 것이 없음에도 소프트웨어는 무엇인가 다를 것이라고 기대를 하거나, 소프트웨어 개발은 특수한 영역이므로 일부러 구별하려는 움직임도 있습니다.
한 가지 확실한 것은 원리, 원칙은 동일하지만, 그 영역에 대해서 다른 의도를 더하려고 할 때 그것 자체가 왜곡이 발생한다는 사실입니다.
이번 글에서는 소프트웨어 모듈이 제대로 만들어지려면 어떤 조건을 가져야만 하는지 살펴보겠습니다. 아마도 이전 모듈러 디자인에 관련된 글을 읽은 사람은 "똑같네"라고 생각할 수 있습니다. 제대로 본 겁니다. 동일합니다.
소프트웨어 모듈은 강력하게 캡슐화가 되어 있어야 합니다. 다른 말로 하면, 블랙박스가 되어야 합니다. 해당 모듈을 사용하려는 누구도 그 소프트웨어 모듈에 대한 코드에 직접 접근해서도, 접근할 필요가 없어야 합니다. 직접 접근할 수 있다는 것을 그것을 수정하거나, 정하지 않은 방식으로 사용할 수 있음을 의미합니다. 이런 사용 형태가 발생하면 예상치 못한 모듈 간의 의존성이 발생하고, 모듈 별로 독립적으로 개발하거나, 수정할 수 없게 됩니다. 소프트웨어 모듈은 내부를 캡슐로 꽁꽁 싸매고 있어야 하고, 그것을 개정하거나, 보완하는 것은 정해진 약속에 따라서 이루어져야 합니다. 그것도 이전 버전 호환성을 고려해서 이루어져야 합니다. 그것이 아닌 수정은 막아야 하고, 사용할 때도 내부를 바라볼 필요도 없이 정해진 절차대로 사용해야 합니다.
"소프트웨어 내부 코드는 숨겨야만 한다."
앞서 캡슐화된 소프트웨어 모듈은 정해진 절차대로 사용을 해야 한다고 했습니다. 사용하는 방식이 인터페이스가 됩니다. 예를 들어서 소프트웨어 모듈은 정해진 인터페이스, 잘 정의된 인터페이스인 잘 알려진 형태가 있습니다. API (Application Programming Interface)입니다. API는 프레임워크, 라이브러리, 클래스 등 재사용 대상을 사용하기 위해서 정해진 함수, 프로시저, 클래스의 형태를 제시한 수단입니다.
API와 같이 캡슐화된 소프트웨어 모듈을 사용하기 위해서 사용할 방식을 알려줘야 합니다. 여기에는 어떻게 구현이 되었는지, 인터페이스 안쪽에서 어떤 메커니즘으로 돌아가는지는 숨겨져 있습니다.
"소프트웨어 모듈을 사용할 수 있는 API를 제공해야 한다."
캡슐화로 내부 코드를 숨기고 있고, 해당 모듈을 사용할 수 있는 통로인 인터페이스를 열어두었다면, 정해놓은 통로인 인터페이스로, 명확하게 의존 관계를 가져야만 합니다. 모듈화에서 모듈 간의 의존성을 최소화하는 것이 중요하지만, 모듈 간의 의존성을 없앤다는 건 모듈들의 집합인 시스템이 작동하지 않음을 의미하기 때문에 의존성을 완전히 배제할 수 없습니다. 대신 의존성을 갖는다면, 정해진 인터페이스를 통해서 명시적으로 의존 관계를 갖는 것이 필요합니다. 그리고, 명시적 의존관계는 순환 형태를 갖지 않도록 해야 합니다. 순환 형태는 모듈끼리 서로 호출하는 관계를 의미하는 데 이것 자체가 의존성을 염두에 두고 이루어지는 행동이기 때문에 철저히 금지해야 합니다.
"모듈 간의 의존 관계는 정해진 약속인 API를 통해서만 갖고, 그 호출 관계는 정해진 형태로 이루어져야 한다."
이번 글에서는 소프트웨어 모듈에 대한 조건에 대해서 알아봤습니다. 모듈러 디자인 원리를 아는 사람에게는 너무나도 당연한 글이고, 소프트웨어 설계를 제대로 하는 사람 입장에서도 어렵지 않은 내용입니다. 즉, 제대로 설계한다면 소프트웨어 모듈화는 특별한 활동은 아닙니다.
Image by Dann Aragrim from Pixabay