이러한 상황이 발생할 수있는 실제 시나리오는 하드 디스크 공간이 매우 제한된 날에 작성된 데이터베이스 라이브러리가 단일 바이트를 사용하여 날짜의 '연도'필드를 저장하는 경우입니다 (예 : 11-NOV-1973). 73그 해에 있을 것 입니다). 그러나 2000 년이되었을 때 이것은 더 이상 충분하지 않으며 연도는 짧은 (16 비트) 정수로 저장되어야했습니다. 이 라이브러리와 관련된 (훨씬 단순화 된) 헤더는 다음과 같습니다.
// dbEntry.h
typedef struct _dbEntry dbEntry;
dbEntry* CreateDBE(int day, int month, int year, int otherData);
void DeleteDBE(dbEntry* entry);
int GetYear(dbEntry* entry);
그리고 '클라이언트'프로그램은 다음과 같습니다.
#include <stdio.h>
#include "dbEntry.h"
int main()
{
int dataBlob = 42;
dbEntry* test = CreateDBE(17, 11, 2019, dataBlob);
//...
int year = GetYear(test);
printf("Year = %d\n", year);
//...
DeleteDBE(test);
return 0;
}
'원본'구현 :
#include <stdlib.h>
#include "dbEntry.h"
struct _dbEntry {
unsigned char d;
unsigned char m;
unsigned char y; // Fails at Y2K!
int dummyData;
};
dbEntry* CreateDBE(int day, int month, int year, int otherData)
{
dbEntry* local = malloc(sizeof(dbEntry));
local->d = (unsigned char)(day);
local->m = (unsigned char)(month);
local->y = (unsigned char)(year % 100);
local->dummyData = otherData;
return local;
}
void DeleteDBE(dbEntry* entry)
{
free(entry);
}
int GetYear(dbEntry* entry)
{
return (int)(entry->y);
}
그런 다음 Y2K의 접근 방식에서이 구현 파일은 다음과 같이 변경됩니다 (다른 모든 항목은 그대로 유지됨).
struct _dbEntry {
unsigned char d;
unsigned char m;
unsigned short y; // Can now differentiate 1969 from 2069
int dummyData;
};
dbEntry* CreateDBE(int day, int month, int year, int otherData)
{
dbEntry* local = malloc(sizeof(dbEntry));
local->d = (unsigned char)(day);
local->m = (unsigned char)(month);
local->y = (unsigned short)(year);
local->dummyData = otherData;
return local;
}
새로운 (Y2K 안전) 버전을 사용하도록 클라이언트를 업데이트해야 할 경우 코드를 변경할 필요가 없습니다. 실제로 다시 컴파일 할 필요조차 없습니다 . 업데이트 된 객체 라이브러리에 다시 연결 하면 충분할 수 있습니다 .
struct내부는 알 수없는 블랙 박스입니다. 클라이언트가 내부를 모르면 직접 액세스 할 수 없으며 마음대로 변경할 수 있습니다. 이것은 OOP의 캡슐화와 유사합니다. 내부는 비공개이며 공용 메소드를 사용하여 오브젝트를 변경하기 만합니다.