사람은 문제 해결에 필요한 요소의 수가 단기 기억의 용량을 초과하는 순간 해결 능력이 급격히 떨어진다. 이런 현상을 인지 과부화라고 한다. 이를 방지하는 가장 좋은 방법은 정보의 양을 조절하는 것이다. 불필요한 정보를 제거하고 현재 문제 해결에 필요한 핵심만 남기는 추상화 작업을 통해 해결할 수 있다.
가장 일반적인 추상화 작업은 한 번에 다뤄야 하는 문제의 크기를 줄이는 것이다. 보통 큰 문제를 해결 가능한 작은 문제들로 나누는 작업인 **분해(decomposition)**을 사용한다. 그리고 이 분해는 소프트웨어 영역의 핵심 논리이다.
프로그래밍 언어는 좀 더 효과적인 추상화를 이용해 복잡성을 극복하려는 개발자들의 노력에서 출발했다. 프로그래밍 언어를 통해 표현되는 추상화의 발전은 프로그래밍 패러다임의 탄생으로 이어졌고 이 패러다임은 프로그램을 구성하기 위해 사용하는 추상화의 종류와 이 추상화를 이용해 소프트웨어를 분해하는 방법의 두 가지 요소로 결정된다.
현대 프로그래밍 언어를 특정 짓는 중요한 두 가지 추상화 메커니즘은 **프로시저 추상화(무엇을 하는지)**와 **데이터 추상화(무엇을 알아야하는지)**다. 프로그래밍 패러다임들은 이 두 추상화를 중심으로 시스템의 분해 방법을 설명한다.
프로시저 추상화를 중심으로 한다면 기능 분해의 길로, 데이터 추상화를 중심으로 한다면 데이터를 중심으로 타입을 추상화하거나, 데이터를 중심으로 프로시저를 추상화한다. 전자를 추상 데이터 타입, 후자를 객체지향이라고 한다.
기능은 오랜 시간동안 시스템을 분해하기 위한 기준으로 사용됐다. 이같은 방식을 기능 분해라고 한다. 이 관점에서 추상화의 단위는 프로시저이고 프로시저를 단위로 분해된다.
프로시저는 반복적으로 실행되거나 유사하게 실행되는 것들을 하나의 장소에 모아 로직을 재사용하고 중복을 방지할 수 있는 추상화 방법이다. 구현 내용을 몰라도 인터페이스만 알면 사용할 수 있어 잠재적으로 정보은닉의 가능성을 제시하지만 프로시저만으로는 한계가 있다.
프로시저 추상화의 한계를 알아보기 위한 예시이다. 직원의 급여를 관리하는 시스템이다. 다음과 같은 구조로 하향식 분해를 통해 분해했다.
이런 방식은 기능이 우선이고 데이터를 기능의 뒤를 따른다. 기능 분해를 위한 하향식 접근법은 먼저 필요한 기능을 생각하고 그에 필요한 데이터의 종류와 저장 방식을 식별한다.
그런데 이런 하향식 기능 분해는 유지보수에 다양한 문제를 야기한다. 이유가 무엇일까? 일단 하향식 기능 분해 방식으로 설계한 시스템은 메인 함수를 루트로 하는 트리구조로 표현할 수 있다. 논리적이고 체계적인 시스템 개발 절차를 제시한다. 큰 기능을 작은 기능으로 단계적으로 정제해가는 과정은 구조적이고 체계적이며 이성적인 방법으로 보인다.
하지만 현실 세계는 그렇게 체계적이지도, 이상적이지도 않다. 체계적이고 이상적인 방법이 불규칙하고 불완전한 인간과 만나며 문제가 생긴다.