0490f719b5826ff620a8d3b706f11a3986e054f7e5dcea193d

인간은 세상을 있는 그대로 인식하지 않는다. 대신 특정한 체계를 형성하며 세상을 이해하려고 한다. 이는 인간의 인식 능력과 세상의 본질적 특성 사이에 근본적인 한계가 있기 때문이다. 세상은 사실상 무한하거나 무한에 가까운데, 인간의 인식 능력은 유한하다. 이런 차이 때문에 세상의 모든 요소를 1대1로 대응하며 이해할 수 없다. 그래서 인간은 세상을 구조화하고 체계화하는 방식으로 제한된 인식 범위 안에서 세상을 이해하고 받아들인다. 이런 과정을 나는 '추상체계'라고 부르기로 한다. 추상체계는 세상을 단순화하고 요약하며 인간의 인식 능력에 맞게 조정하는 일종의 필터 역할을 한다. 인간이 만든 추상체계는 이론적으로 무엇이든 될 수 있을 것 같다. 하지만 무한히 자유로운 방종은 비효율적이며, 결국 특정한 방향으로 귀결되는 경향이 있다. 그 경향성 중 하나는 추상체계가 특정한 중심개념을 갖는다는 점이다. 추상체계는 이 중심개념을 중심으로 하여 구조화되고, 주변 요소들은 이 중심개념을 보완하거나 확장하는 방식으로 배치된다. 이는 중심잡기가 효율적이기 때문이기도 하지만, 결국 추상체계란 '아'의 투영이기 때문이다. '아'의 인식은 근본적으로 '비아', 즉 나를 제외한 세계를 전제로 한다. '자각'이란 곧 '아'와 '비아'를 나누는 행위이며, 그렇기 때문에 본질적으로 이분법적이다. 이렇게 투영된 '아'는 만물에 '아'를 반영하며, 이를 통해 세상을 '아'와 유리된 독립된 오브젝트로 체계화한다. 그 결과, 세계는 각기 떨어져 있는 객체들이 서로 얽히고 설키며 복잡한 구조를 이루는 체계로 변화한다. 추상체계는 '아'의 관점에서 세상을 조각내고, 각 조각에 이름과 역할을 부여함으로써 세상을 정리한다. 그러나 이 과정 자체가 세계와 '아'를 근본적으로 분리된 것으로 상정하기 때문에, 우리가 만든 체계는 항상 투영된 '아'를 중심으로 돌아가게 된다. 즉, 인간이 만든 모든 복잡한 체계는 결국 '아' 혹은 '자아’를 투영하기 좋은 오브젝트, 중심 오브젝트를 기준으로 구성되는 경향이 있다. 이는 그 체계가 세계의 본 모습을 잘 표현하기 때문이라기보다는, '자아'를 가진 인간이 '자아'를 중심으로 인식하는 방식이 더 자연스럽고 익숙하기 때문이다. 다른 방식의 인식이 존재할 수 있는지는 알 수 없다. 나 역시 자아를 가진 인간이기에, 자아를 중심으로 한 인식 외의 다른 방식을 경험하거나 이해할 수 없다. 결국, 인간이 만든 체계는 인간 자신의 인식 구조를 반영하는 틀일 수밖에 없다. 이것은 OOP(Object-Oriented Programming)가 무엇이든 될 수 있을 것처럼 보이지만, 아이러니하게도 그 무한한 가능성이 비효율의 원인이 되기도 한다. 아무런 제약 없이 모든 것을 표현할 수 있다는 점은 오히려 구조적 혼란을 초래하며, 체계의 명확성과 효율성을 저해할 가능성이 크다. OOP의 본질은 객체를 중심으로 세상을 추상화하고 구조화하는 데 있지만, 만약 그 중심 없이 무작위로 설계된다면, 객체 간의 관계와 역할이 모호해지고 관리가 어려워진다. 결국, OOP의 본질은 그 가능성의 무한함이 아니라, 중심이 되는 객체와 그 주변을 조직적으로 설계함으로써 얻어지는 체계성과 확장성에 있다. 그리고 그러한 구조적 중심을 무엇으로 설정할지에 대해서는 많은 고민이 필요하다. 그러나 나는 이렇게 주장한다. 무엇을 구현하든, 중심적인 데이터베이스를 설계의 중심에 두는 것은 대체로 손해를 보지 않는 선택이 될 것이다. 이는 단순히 데이터베이스 중심으로 작동하는 전통적인 프로그램들(예: 고객 관리 시스템, 재고 관리 시스템 등)뿐만 아니라, 게임과 같은 시뮬레이션 프로그램에서도 마찬가지로 적용된다. 그렇게 중심 데이터베이스를 설계한다면, 이후에는 다음과 같은 구현적 문제들이 발생한다. 어떠한 형태로 데이터베이스를 설계할 것인가. 데이터베이스를 가공하는 함수는 어떻게 작성할 것인가. 하지만, 이러한 구현적 문제에 앞서 먼저 생각해야 할 중요한 전제가 있다. 그것은 바로 핵심 데이터베이스는 중심적인 정보만 담고 있어야 한다는 점이다. 이를 웹 프로그래밍의 구조를 예로 들어 생각해 보면 이해가 쉽다. 웹은 다른 분야에 비해 이런 구조적 분리가 특히 잘 이루어져 있다. 웹 개발은 종종 상대적으로 지능이 낮거나 경험이 부족한 사람도 쉽게 접근할 수 있는 분야로 업신여김을 받는 경우가 있다. 하지만 이를 달리 보면, 인력의 수준이 다소 낮더라도 최소한 동작하는 코드를 만들 수 있을 정도로 구조적으로 체계가 잡혀 있다는 의미이기도 하다. 웹은 HTML, CSS, 라는 세 가지 기본 요소로 역할을 명확히 나누었다. HTML은 구조를 담당하고, CSS는 디자인을, 는 동적인 기능을 처리한다. 그리고 그 중에서도 데이터의 핵심이 되는 중앙 데이터 부분은 SQL 같은 데이터베이스 시스템을 활용해 따로 관리하도록 모듈화되었다. 이런 분리와 모듈화는 단순히 보기 좋은 구조가 아니라, 웹의 특성상 빠른 개발과 유지보수를 가능하게 하는 현실적인 선택이다. 데이터를 중심에 두고, 그 데이터를 표현하거나 조작하는 부분은 다른 층에서 처리하도록 한 이런 구조. 이러한 구조는 명백한 이점을 가지고 있다. 바로 특정한 변화를 주기 위해 코드 전체를 바꿀 필요가 없다는 점이다. 가령, 특정 데이터를 변경했을 때 관련된 그래픽이나 음향 데이터를 모두 동시에 수정해야 한다고 상상해 보자. 예를 들어, 게임에서 플레이어의 체력 수치를 업데이트할 때, 그 수치와 연관된 체력 바의 크기, 체력 감소 효과음, 화면의 경고 표시까지 직접적으로 수정해야 한다면, 이는 매우 비효율적이고 엉망인 코드 구조일 것이다. 반면, 구조적으로 데이터와 표현, 동작이 분리되어 있다면, 중심 데이터만 변경해도 그 변화가 자연스럽게 그래픽이나 음향 등 다른 영역에 반영되도록 할 수 있다. 이를 통해 유지보수성이 높아지고, 확장 가능성이 크게 향상된다. 데이터와 표현, 동작이 독립적으로 관리되기 때문에 하나의 변화가 전체 시스템에 불필요한 영향을 주지 않도록 할 수 있는 것이다. 그리하여 중심 코드가 무엇인지를 명확히 파악하면, 코드는 변증법적으로 개선될 수 있다. 여기서 핵심은 단순히 코드가 개선된다는 결과 그 자체가 아니라, 설계 단계에서부터 변증법적으로 중심 코드를 개선하기 쉽도록 구조를 잡는 데 있다. 코드의 중심이 되는 부분이 명확하게 정의되고, 그 주변 요소들이 이 중심을 보조하거나 참조하도록 설계되면, 중심 코드의 변경이 다른 부분에 자연스럽게 반영되도록 할 수 있다. 이를 통해 변화와 발전이 필요할 때 전체 시스템이 혼란에 빠지지 않고 유연하게 적응할 수 있다. 결국, 중요한 점은 처음부터 설계를 할 때 중심 코드를 쉽게 개선할 수 있는 방향으로 구조를 잡는 것이다. 이는 처음에는 접근이 쉽지 않을 수 있다. 무엇이 중심적인 내용의 코드이고, 무엇이 추가적인 표현형인지 구분하는 것이 혼란스러울 수 있기 때문이다. 그러나 이런 혼란도 결국 "데이터"를 중심으로 프로그래밍한다는 관점을 가지면 비교적 간단하게 해결할 수 있다. 해결 방법은 특정 상태를 데이터베이스로 어떻게 표현할 것인지를 먼저 모델링하는 것이다. 예를 들어, 게임이라면 플레이어의 체력, 위치, 소지품 등을 데이터베이스에서 어떻게 구조화할지를 설계한다. 그런 다음, 이 모델링에 따라 특정 상태를 명확히 표현할 수 있는 데이터베이스를 구현한다. 이렇게 데이터베이스를 중심으로 상태를 정의하고 관리하면, 표현형이나 동작은 데이터베이스의 상태를 참조하거나 수정하는 역할로 나뉘게 된다. 이 과정을 통해 중심 코드와 부수적인 표현형을 자연스럽게 분리할 수 있고, 무엇을 중심으로 설계해야 하는지 감이 잡히게 된다. 상태 데이터 구조를 명확히 정의한 다음에는, 그 데이터를 조작할 함수들을 설계해야 한다. 이러한 함수들은 상태 데이터를 읽고 쓰는 역할을 하며, 이후 상태가 시시각각 변화하도록 시스템을 설계한다. 이때 상태 변화는 표현 담당 레이어를 통해 확인할 수 있어야 하며, 이를 바탕으로 상태 데이터베이스와 조작 함수들을 지속적으로 개선해야 한다. 하지만 상태를 조작하지 않고 단순히 출력만 담당하는 표현 레이어의 경우, 처음부터 완벽하게 만들 필요는 없다. 우선 중요한 것은 상태 데이터와 연동되도록 구현하고, 내가 확인하기 쉽도록 알아보기만 쉽게 만드는 것이다. 표현의 완성도는 상태 데이터가 올바르게 구현된 이후에 신경 써도 늦지 않다. 이 단계에서는 얼마나 시각적으로 정교하게 표현했는지가 아니라, 표현 레이어를 통해 주 로직을 확인하고 개선할 수 있느냐가 핵심이다. 표현이 단순하고 미완성이라도, 상태 데이터와 함수가 제대로 작동하는지 테스트하고 피드백을 받을 수 있는 도구로써 기능하면 충분하다. 물론 실제 프로그래밍에서는 모든 것을 하나의 데이터, 기능, 표현이라는 3개 레이어로만 나눠서 처리할 수는 없다. 작은 프로그램이라면 가능할지도 모르지만, 프로그램 규모가 커지면 모든 요소를 이 세 가지 레이어에만 쑤셔 넣는 것은 오히려 비효율적이 될 것이다. 예를 들어, 특정 기능이 너무 복잡해지면 그 자체만으로도 데이터, 기능, 표현(이 표현이 완성된 프로그램의 일부이든, 개발 과정에서 피드백을 위해 임시로 사용하는 것이든 간에)이 따로 필요한, 일종의 작은 프로그램처럼 작동하게 될 수 있다. 이때 중요한 점은, 표현 레이어의 목적이 엔드 유저에게 최종적으로 보여질 것만이 아니라, 현재의 내가 피드백을 잘 받을 수 있도록 돕는 도구 역할을 한다는 점이다. 이는 복잡한 시스템의 개발 과정에서 매우 중요한 부분이다. 이처럼 복잡도가 높아질 때는 재귀적인 구조를 활용하는 것이 자연스러운 선택일 수 있다. 즉, 큰 프로그램 속에서 개별적인 기능이나 모듈을 작은 프로그램처럼 나누어, 각각 데이터, 기능, 표현의 레이어를 가지게 만드는 것이다. 반면, 상황에 따라서는 재귀적 설계가 과도하게 복잡해질 위험이 있다. 이럴 때는 단순히 큰 틀에서만 레이어 구조를 적용하고, 세부적인 부분에서는 임시적인 땜빵 방식으로 처리하는 것이 더 효율적일 수도 있다. 결국 중요한 것은 프로그램의 복잡성을 어떻게 적절히 관리할 것인가의 문제이며, 재귀적 설계와 땜빵 방식 중 어느 쪽이 더 나은지는 프로그램의 목적과 상황에 따라 유연하게 선택해야 한다는 점이다.