Một kịch bản trong thế giới thực có thể xảy ra là khi thư viện cơ sở dữ liệu, được viết vào những ngày mà không gian đĩa cứng rất hạn chế, đã sử dụng một byte duy nhất để lưu trữ trường 'năm' của một ngày (ví dụ: 11-NOV-1973 sẽ có 73
trong năm). Nhưng, khi Năm 2000 xuất hiện, điều này sẽ không còn đủ nữa và năm đó phải được lưu trữ dưới dạng một số nguyên ngắn (16 bit). Tiêu đề có liên quan (đơn giản hóa nhiều) cho thư viện này có thể là:
// dbEntry.h
typedef struct _dbEntry dbEntry;
dbEntry* CreateDBE(int day, int month, int year, int otherData);
void DeleteDBE(dbEntry* entry);
int GetYear(dbEntry* entry);
Và chương trình 'khách hàng' sẽ là:
#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;
}
Việc thực hiện 'bản gốc':
#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);
}
Sau đó, theo cách tiếp cận của Y2K, tệp triển khai này sẽ được thay đổi như sau (mọi thứ khác không bị ảnh hưởng):
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;
}
Khi khách hàng cần được cập nhật để sử dụng phiên bản mới (Y2K an toàn), sẽ không yêu cầu thay đổi mã. Trong thực tế, bạn thậm chí có thể không phải biên dịch lại: chỉ cần liên kết lại với thư viện đối tượng được cập nhật (nếu đó là những gì) có thể là đủ.
struct
là một hộp đen với nội bộ không rõ. Nếu khách hàng không biết nội bộ, nó không bao giờ có thể truy cập trực tiếp vào chúng và bạn có thể thay đổi chúng theo ý muốn. Điều này tương tự như đóng gói trong OOP. Các phần bên trong là riêng tư và bạn chỉ thay đổi đối tượng bằng các phương thức công khai.