디자인 패턴 #2: MVC는 해롭다?
Ask for help, not for information.
객체는 어떻게 하는지를 말하지 않고 무엇을 하느냐를 말한다. 객체지향은 객체의 세부적인 구현을 다른 객체가 모르게 함으로서 데이터의 전역 결합을 끊는 패러다임이다. 만약 객체가 무엇을 하는지를 정의하지 않고 어떻게 하는지를 정의하게 된다면 한 객체의 세부 구현을 다른 객체가 알 수 있게 되고 객체 모델을 통한 데이타 추상화가 이루어질 수 없다. 대부분의 개론서는 객체를 데이터와 메서드의 집합으로 묘사하고 있는데 세부 구현에 신경을 쓰기 때문에 좋지 못한 서술이라고 볼 수 있다.1
물론 데이터의 전역 결합으로 문제가 해결되는 것은 아니다. 쉬운 문제는 쉬운 것이고 어려운 문제는 어려운 것. 하지만 복잡한 문제가 데이터의 전역 결합으로 엮이어 있는 것을 풀어주는 것만으로도 복잡성은 조직화되고 더 쉽게 관리가 된다. 해당 도메인의 문제를 적절한 객체에 조직화를 하게 됨으로서 앞으로 어떤 부분만 코드를 수정하고 추가해야하는지 명확해진다.
사용자의 이름을 받는 시스템을 가정하자. 이 시스템은 TextField가 있고 String으로 값을 받아 올 수 있을 것이다. 실제 구현이 어떻게 이루어질 것인지에 먼저 중점을 두고 있는데 이런 관점을 절차지향 패러다임이라고 부른다. 이런 절차 지향 방법에서는 문제가 조금 바뀌는 경우 광범위한 수정이 이루어질 수 밖에 없다. 만약 유니코드로 다룰 수 없는 중국어를 다룬다면 당장 String 대신에 다른 무엇을 써야한다. 펜이나 음성을 통한 이름 입력을 지원할 경우, 갑자기 사원번호도 다뤄야 하는 경우. 요구사항이 변경될 때 마다 광범위한 수정이 일어난다. 중국어를 다루는 일, 펜과 음성을 다루는 일은 원래 쉬운 일이 아니라 어떤 방법으로도 간단히 만들 수 없다. 하지만 무언가 요구사항이 바뀌어서 광범위한 영역에 발생하는 코드 수정은 충분히 우리가 예방할 수 있다.
조금 더 나은 방법은 자신이 해결책을 가지고 있는 Name을 쓰는 것이다. Name 객체를 쓰고 Name에게 Graphic이나 Container를 주어 적당한 정책을 가지고 있는 Name이 스스로 자신을 화면에 출력하게 하는 것이 더 나은 접근이다. Name이 어떻게 데이터를 받아서 어떻게 처리하는지는 더 이상 신경쓸 필요가 없다. 심지어 Name은 Graphic이나 Container에 이름을 출력할지 DB나 네트워크를 이용해서 처리할 것인지도 정할 수 있다.
우리가 자주 쓰고 있는 패턴인 MVC의 경우에는 조금 더 나은 방법이 아니라 바람직하지 않는 방법에 가깝다. 우리의 어플리케이션은 프레젠테이션으로부터 입력 값을 얻어와서 (pull) 내부에 있는 데이터 처리 로직에 넣어 데이터를 처리한다. (push) MVC의 경우 너무나 많은 데이터가 get/set (혹은 push/pull)의 형태로 돌아다니게 되고 컨트롤러가 모델과 뷰에 대해 깊게 알아야 하며 너무 많은 데이터가 돌아다니며 시스템을 유지시킨다.
-
객체를 if를 적게 쓰는 테크닉으로 보는 시선도 있는데 객체의 역할과 협동이 아닌 지엽적인 제어 구조로 객체의 관점을 한정시키기 때문에 놓치는 것이 많은 관점이다. ↩