본문 바로가기
객체지향설계

[파일구조] - 파일구조 설계 I

by CHML 2016. 4. 23.

이 글의 소스 코드는 File Structures: An Object-Oriented Approach with C++ 3rd Edition의 내용을 수정하여 작성한 것 입니다.


1. 데이터 클래스 내부에 연산 구현

앞의 글에서 필드와 레코드를 저장하는 다양한 방식을 소개했다. 각각의 방식은 구현 목적과 실행 환경에 따라 장단점이 존재하기 때문에 좋은 파일구조는 다양한 저장 방식을 지원해야 한다. 다양한 저장 방식을 지원하도록 파일구조를 구현하기 위해 가장 쉽게 생각해볼 수 있는 방법은 데이터 클래스 내부에 read/write 연산을 구현하는 것이다. 예를 들어, 아래의 코드처럼 Person 클래스에 고정 길이, 길이 지시자 등의 방식으로 레코드를 읽는 read/write 연산을 구현할 수 있다. 아래의 코드에서 필드 구분은 구획 문자 방식을 이용하며, string.valueOf 함수는 문자열 타입이 아닌 데이터를 문자열 타입으로 변경하는 함수이다.

read/write 연산을 파일 내부에 구현하는 것은 아래와 같이 구현상에 치명적인 문제를 발생시킨다.


  • 만약 4개의 필드 구분 방식과 5개의 레코드 구분 방식이 존재한다면, 클래스 내부에 총 20개의 함수를 정의해야 한다.
  • Person 클래스 이외에도 파일시스템에 Animal과 같은 다른 데이터 클래스를 추가하는 경우에는 Animal에도 Person 클래스처럼 총 20개의 함수를 다시 정의해야 한다.
  • 새로운 저장 방식을 추가하고자 하면 모든 데이터 클래스의 구현 내용을 수정해야 하는 문제가 발생한다. 


2. 버퍼 클래스에 연산 구현

데이터 클래스 자체에 연산을 구현하는 방식은 유지 및 보수상에 많은 문제점을 초래한다. 따라서, 각각의 필드 및 레코드 저장 방식을 지원하는 버퍼 클래스를 따로 정의하고 데이터 클래스를 버퍼 클래스에 인자로 전달하는 방식으로 파일구조를 구현하는 것이 더욱 합리적인 방법이다. 예를 들어, 구획 문자 방식으로 필드를 구분하는 DelimTextBuffer는 아래와 같이 구현될 수 있다.

DelimTextBuffer에 구현된 pack 함수는 데이터 클래스의 필드 하나를 버퍼에 쓰는 기능을 하고, unpack 함수는 버퍼에서 하나의 필드를 데이터 클래스로 읽어오는 기능을 한다. DelimTextBuffer의 write와 read 함수는 버퍼 단위로 파일 입출력을 수행하는 함수이다.



Person 클래스를 파일에 저장하기 위해 DelimTextBuffer를 사용하는 경우, 아래와 같은 코드를 작성하면 된다. Person 클래스의 id와 age는 정수형 데이터이지만, 아래의 코드에서는 문자열로 변환되었다고 가정한다.

데이터 클래스 자체에 pack과 unpack 함수를 구현하는 것이 아니라 버퍼 클래스를 따로 구현하여 pack과 unpack 함수를 구현하면, 새로운 데이터 클래스인 Animal이 추가되어도 Animal 클래스 내부에 pack과 unpack 함수를 구현할 필요가 없다. 만약 이미 구현된 DelimTextBuffer를 그대로 이용하여 Animal 클래스를 파일에 쓰기 위해서는 위의 코드를 조금만 변형하면 된다. 예를 들어, DelimTextBuffer를 이용하여 Animal 클래스를 파일에 쓰기 위해서는 아래의 코드와 같이 프로그램을 작성하면 된다.

데이터 클래스 이외의 Buffer 클래스를 따로 구현함으로써 새로운 데이터 클래스가 추가되어도 쉽게 파일 연산을 구현할 수 있게 되었다. 그러나 버퍼 클래스를 이용하는 경우에도 아래와 같은 세 가지 문제점이 존재한다.


  • 개념적으로 볼 때, 버퍼 클래스를 이용하는 것은 데이터를 파일에 쓰는 것이 아니라 버퍼에 쓰는 것이다.
  • 메인 함수에 데이터 클래스를 pack, unpack 하는 과정이 모두 드러나기 때문에 객체지향프로그래밍 관점에서 볼 때 바람직하지 않은 설계가 된다.
  • 메인 함수에 pack, unpack 하는 모든 과정을 작성해야 하기 때문에 메인 함수의 코드가 복잡해지고 길어진다.
위의 세 가지 문제점을 해결하기 위한 방법은 다음 글에서 설명한다.