Можливий сценарій у реальному світі, коли це відбудеться, коли бібліотека баз даних, написана в дні, коли місце на жорсткому диску було дуже обмеженим, використовувала один байт для зберігання поля 'рік' дати (наприклад, 11-НОВ-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це чорний ящик з невідомими внутрішніми. Якщо клієнт не знає внутрішніх справ, він ніколи не може отримати доступ до них безпосередньо, і ви можете змінити їх за бажанням. Це схоже на інкапсуляцію в ООП. Внутрішні внутрішні дані є приватними, і ви змінюєте об'єкт лише публічними методами.