재미있게 주몽을 보고 잠깐 들어와 보니 이런 저런 다양한 글들이 Context 개체가 남발되고 있다거나, 의미의 면적이 좁은 인터페이스를 제공하거나 그에 의존해서는 안된다거나, 최소 권한의 원칙과 같은 이야기를 하고 있습니다.
다 맞는 말씀입니다만, 저는 이런 원칙들의 궁극적인 목표를 생각해야 할 필요가 있다고 봅니다. 그것은 바로 소프트웨어 개발 비용을 절감시키는 것입니다. 소프트웨어 비용을 절감시켜야 한다고들 주장한다면 보나 마나 소프트웨어 비용이 늘어났다는 뜻이겠군요. 그렇다면 소프트웨어 개발 비용은 왜 늘어났을까요? 그것은 더 복잡한 소프트웨어를 만들어 내야 하기 때문입니다. 오늘날 모든 복잡한 소프트웨어는 다른 더 작은 소위 컴포넌트라 불리우는 소프트웨어에 기반해 개발되고 있습니다. 바꿔 말하면, 오늘날의 불필요한 소프트웨어 개발 비용 지출의 대부분이 의존하는 API의 사용성 (usability) 문제 때문에 발생하고 있다고 할 수 있습니다. 사용성 나쁜 API를 노출하는 컴포넌트를 사용하면 monolithic 하게 개발했을때처럼 생산성이 떨어질 수도 있습니다.
그런데 이 API의 사용성이란 것은 사실상 평가가 어려운 광범위한 분야로, 보통 객체 지향 설계 원칙이라는 고상한 말로 포장되어 왔습니다. 개발자의 입장에서 이 둘은 동의어나 마찬가집니다.
사용성이 높은 API는 전부를 모르더라도 쉽게 기본적이면서도 실무에 필요한 핵심적인 작업을 바로 시작할 수 있고, 좀 더 복잡한 케이스를 다뤄야 할 경우 다음 단계를 쉽게 배워 나아갈 수 있도록 학습 곡선을 정교하게 제어합니다. 그 과정에서 물론 과정보 (overinformation)은 억제됩니다. 즉, 누구나 빠르면서도 자신이 모르는 사이에 발전 가능한 방향으로 원하는 바를 성취하고, 학습의 즐거움을 느낄 수 있게 해 주는 것이 API 사용성의 핵심입니다.
그렇다면 Context 객체가 어떤 문제를 갖느냐, Context 객체 자체의 도입은 API 사용성 측면에서 매우 고무적입니다. 컨테이너나 커널이 제공하는 기능을 활용하여 동작하는 비즈니스 로직이 부모 컨테이너/커널이 노출하는 최소한의 기능만을 사용할 수 있도록 해 주는 개체가 Context 의 원래 역할이기 때문입니다. 첫 번째 글에서 static 하거나 ThreadLocal을 사용한 Context 객체를 예로 들었는데, 이는 부적절한 예입니다. static 하거나 ThreadLocal 하게 작성했다는 것이 문제이지, Context 객체 자체의 존재가 잘못된 것은 전혀 아닙니다. 문제가 있다면 Context 를 제공하는 컨테이너의 역할 정의가 모호했기 때문이겠죠. 그도 아니면 컨테이너도 아니면서 주제 넘게 intrusive한 인터페이스를 제공했기 때문이겠죠. 컨테이너나 프레임워크가 Context 개체를 제공하는 것은 전혀 잘못된 일이 아닙니다.
또한, 두 번째 글에서 이야기하고 있는 다양한 Context 개체가 한 코드에서 섞여서 쓰이는 문제는 그 코드가 동시에 다양한 기능을 사용하려고 했다는 뜻을 가질 뿐입니다. 동시에 여러 가지 일을 한다는 것이 항상 잘못된 것은 아니며, 적절한 검토가 필요할 따름입니다. 오캄의 면도날을 쫓는 것은 좋은 일이지만, 의존성에 지나치게 집착하는 것도 좋은 태도는 아닙니다. 클래스 하나 때문에 수백KB 짜리 JAR 쓰는게 왜 나쁩니까? 클래스 하나를 씀으로 인해 다른 원치 않는 부작용이 생겨야 나쁘지, 대부분의 잘 설계된 컴포넌트들은 그렇지도 않습니다. 글쓴이가 HTMLPageParser 하나 때문에 SiteMesh 를 사용한 것처럼요. 문제는 하고자 하는 일에 맞는 제대로 된 컴포넌트를 선택하는 것이지, 컴포넌트를 사용하느냐 마느냐가 아닙니다.
어떤 API 를 설계할 때 결과적으로 중요한 것은, 대상 – 엄밀히 말하면 다수의 – 사용자가 그 API를 편리하게 느끼느냐입니다. API가 불필요하게 많은 기능을 제공한다 하더라도 그것이 결국 그 API를 사용하는 대상이 편하게 느끼고 결과적으로 생산성을 가져다 주면 저는 상관 없다고 봅니다. 과연 관계의 수를 줄여 결국에는 다 제공해야 할 기능을 매우 복잡한 콜 그래프를 그리게 해야 할 필요가 있을까요? 전 당연히 없다고 봅니다. Humane interface 와 Minimal interface 에 대한 논쟁에서와 마찬가지로, 사용자가 얼마나 많은 정보에 노출되기를 바라느냐에 따라 호불호가 갈릴 뿐 정답은 없습니다.
중요한 것은 특정 원칙에 집중하는 것이 아니라, API 를 사용하게 될 사람의 마음을 헤아리고 그 사람이 가장 생산성 있게 개발할 수 있도록 하는 것입니다. 또한 나아가 사용자가 감동할 수 있는 API 를 제공해 그 설계 철학이 그 사용자가 개발하고 있는 컴포넌트에 전해질수 있도록 한다면 금상 첨화겠죠. 이것은 단순히 다양한 원칙들을 고수함으로서 이루어지는 것이 아니라 다분히 사용자층의 취향과도 결부되는 복잡한 상호작용의 결과, 즉, 매우 사회적인 과정입니다.
그러므로 우리는 오늘날 컴포넌트들이 얼마나 사용자를 고려해서 개발되고 있는지 생각해 볼 필요도 있습니다. 유명한 라이브러리나 프레임워크들을 보면 사용자층도 두텁고 피드백도 활발합니다. 닭이 먼저냐 계란이 먼저냐는 질문을 할 수도 있겠지만, 적절한 원칙을 세워 개발하였고, 그 과정에서 생길 수 있는 API의 까칠한 면을 커뮤니티의 도움을 받아 다듬어 나아가는 것이 지금까지 제가 보아 온 성공한 소프트웨어의 모습이었습니다. 원칙도 중요하지만 그 뒤에는 사용자가 있다는 것, 그리고 그 사용자와 상호작용이 제대로 이루어지지 않으면 그 좋은 원칙도 아무 소용 없다는 것 또한 명심해야 합니다.
‘마음을 헤아리고..’
역시, core는 마음에.. ^^
전적으로 동감합니다. 전 이번 주에 시간이 많으니 같이 한 번 이야기 해보면 재밌겠어요. 🙂