파일, db, 네트워크 어떠한 기반 장치로부터인지에 관계 없이 데이터가 구축될 때 구조를 두 가지로 나눌 수 있을 것 같다.
(편의상 의미를 알아볼 수 있는 정도의 수도Pseudo 코드를 사용하였습니다. 그런 API 없는데요? 라고 하시면 곤란합니다 :-D)
1. 정형화Normalize된 데이터 구조라고 명명함. 혹은 목적형For Objective 스크립트라고 해도 되겠다(내 맘대로 명명했다).
이러한 데이터들은 코드에서 직접적인 행위를 통해 접근이 가능한 집단이다. 완전히 일반적인 언어를 만들고 있지 않는 한 데이터의 가공 및 처리 편의성을 위해 명확한 목적을 지닌 하드코딩 연결부가 존재하는데,
<server ip="192.168.0.1" port="15000" />
----------------------------------------------------------------
if(!LIB_NET::connect(xml["server"]["ip"], xml["server"]["port"]))
{
cout << "접속 실패" << endl;
return 1;
}
와 같은 예가 정형화된 데이터를 사용한 예다. 코드는 명확하게 xml 로 server 가 존재함(예외 처리가 추가될 수 있다고 하더라도)을 알고 있으며 "server" 라는 토큰은 명확히 어딘가로의 접속을 위해 사용되는 매개체가 된다. 조금 더 시간을 투자한다면 복잡한 일반화를 통해 코드에서 server 를 직접적으로 활용하여 connect 를 호출하지 않고 스크립트에 코드를 두며 해당 parser 를 제작하는 식으로 처리할 수도 있지만, 웬만큼 크지 않은 프로젝트 대부분에서 이는 낭비에 속할 것 같다.
정형화된 데이터는 개발자 입장에서 읽고 쓸 때 명쾌하며 빠른 개발 속도도 보장한다.
빠른 대신 독립성의 이점은 별로 없다. 개발자가 모두 관리한다고 가정했을 때 이런 어중간한 데이터의 분리보다는 차라리 코드로 한 몸에 있는 것이 훨씬 낫다.
즉, 장단점을 하나로 정리하자면,
독립성, 관리비용 : 동적 데이터 구조 > 목적형 구조 > 코드
위와 같은 어중간한 방법이 가장 좋은 효율을 내는 경우가 아이템 1,000개를 만들 때 제작자와 개발자가 다른 경우다. 이때 목적형 스크립트는 서로 간에 의사소통 비용을 적절히 조율할 수 있고 요구사항/제공사항을 명확하게 나열할 수 있어 데이터의 1차 관리로 많이 활용되는 것으로 보인다.
<name> 아이템 이름
<stat> 아이템을 착용했을 때 증가하는 스탯 정의부
<desc> 아이템 설명
와 같은 명세서가 있다고 할 때 제3작업자인 스크립터는 쉽고 빠르게 단순반복 작업이 가능하다.
그러나 이 방식의 치명적인 단점이 있는데, 재활용하는 스크립트의 수가 적은 곳에 사용되면 1회용 코드가 난무하게 된다는 것이다. 위의 connect 에 사용된 server 정보와 같은 예다.
2. 동적Dynamic 데이터 구조
위의 구조를 좀 더 발전시켰다, 라는 개념보다 반대의 구조를 찾는다고 하면 동적 데이터 구조다. 목적형 구조는 하드코딩을 발전시킨 개념으로 보이지 하드코딩과 반대 개념이라고 보여지진 않는다.
동적 데이터 구조는 말 그대로 언어의 처리 방식과 비슷하다. 데이터가 얼마나 들어올 지, 무슨 데이터가 들어올 지 정해져 있지 않기 때문에 정형화된 모양으로 읽어들일 수가 없다.
<color name="black" r=0 g=0 b=0 />
<color name="blue" r=0 g=0 b=255 />
<color name="yellow" r=0 g=255 b=255 />
위와 같은 데이터는 얼마나 중복으로 들어올 지 알 수 없다. 동적 데이터를 처리하는 구조가 더욱 복잡해지는 이유는, 무엇이 들어올 지도 잘 모르지만 "얼마나 중복이 생길 지"도 잘 모른다는 사실이 더욱 구조를 복잡하게 만든다. 단순히 위의 예를 처리하려고 해도 정형화된 아이템 구조에서는 필드 하나로 끝날 스크립트가 리스트 구조 등을 요구하게 된다.
동적 데이터 구조는 코드에서 명확하게 그 대상을 지칭할 수 없다는 문제를 항상 염두에 두어야할 것 같다. 그렇게 만들려고 한다면 못 할 것은 없겠지만, 스크립트로 만든 데이터들을 코드에서 임의대로 지칭하려면 고려해야할 것들이 꽤 많다. 생성 영역과 관리 영역domain 이 다르기 때문이다. 반면, 스크립트에서 만들었다면 스크립트에서 해당 구조를 지칭하는 것은 그리 어렵지 않다.
<text color="yellow">안녕하세요?</text>
만약 yellow 가 하나 더 추가되어 2개가 되었을 경우 이를 코드 영역에서 지칭하려면 수정 후 리빌드 과정이 필요하지만, 같은 스크립트 레이어에서 이를 지칭하기 위해선 그냥 식별자identifier 만 수정하면 된다. 이는 코드에서 만든 것을 스크립트에서 지칭하기 어려운 이유와도 일맥상통하는데, 결국 관리자가 다르다는 것이 이유인 것 같다.
그래도 사용을 하려고 들면 못 하진 않는다. 다만 다음과 같은 일이 생기면 껄끄러운 것은 나 뿐인가?
while( xml["color"].IsValid() )
colormap[xml["color"]["name"]] = RGB( xml["color"]["r"], xml["color"]["g"], xml["color"]["b"] );
------------------------------------------------------------------------------------------------
DrawLine(10, 10, 100, 100, colormap["black"]);
동적 스크립트로부터 얻은 데이터로부터 특정 키 값을 주어 라인을 그릴 때 색상 값을 취하고 있다. 아마 이 스크립트에는 다음과 같은 주석이 항상 따라다닐지도 모르겠다.
<color name="black" r=0 g=0 b=0 /> <!-- 코드에서 사용하고 있으니 변경 시에 개발자에게 문의하세요 -->
저런 경우가 많아지면 설계 상으로 꽤 곤란할 것 같은데, 나만 그렇게 느끼는 건지도 모르겠다.
위의 두 가지를 모두 지원하려니, 라이브러리가 DOM 형식과 반복자 형식을 항상 같이 지원해야 한다.
작금의 많은 XML 라이브러리들을 위시하여 스크립트 파서나 데이터 관리자 클래스들이 두 가지 모양을 모두 지원하는 이유에 대해 짧게 고찰해보았다.
DOM 형식이 코드도 보기 예뻐서 좋은데, 여러 모로 참 귀찮다. 으아아아아아!!!!!!!
결론은 한탄 뻘글