C言語でGoFのAdapterパターンを実装します。
Adapterパターンを確認する
まずはAdapterパターンを確認しましょう。TECHSCOREさんのAdapterパターンの解説記事をご参照ください。
https://www.techscore.com/tech/DesignPattern/Adapter/Adapter1.html/
Adapterパターンで設計する
TECHSCOREさんのサンプルコードをC言語に移植します。C言語は多重継承ができないため、継承ではなく、委譲を使ったAdapterパターンを使います。クラス図にすると次のようになります。

Adapterパターンを実装する
Charpersonを作る
ChairpersonがTeacherが使用したいインタフェースです。これはそのままC言語に移植できます。
Chairperson.h
typedef struct Chairperson {
void (*organizeClass)(struct Chairperson *chair);
} Chairperson;
extern void Chairperson_organizeClass(Chairperson *chair);
Chairperson.c
void Chairperson_organizeClass(Chairperson *chair) {
chair->organizeClass(chair);
}
Taroを作る
Taroさんを作りましょう。彼はenjoyWithClassmatesメソッドを持っています。後、特に意味はありませんが11才という設定にしておきます。
Taro.h
typedef struct TaroStruct Taro; extern Taro *Taro_create(); extern void Taro_destroy(Taro *taro); extern void Taro_enjoyWithAllClassmates(Taro *taro);
Taro.c
typedef struct TaroStruct {
uint16_t age;
} TaroStruct;
Taro *Taro_create() {
Taro *taro = (Taro*)malloc(sizeof(Taro));
taro->age = 11;
return taro;
}
void Taro_destroy(Taro *taro) {
free(taro);
}
void Taro_enjoyWithAllClassmates(Taro *taro) {
printf("enjoy all!");
}
Hanakoを作る
Adapterとして動いてくれるHanakoさんを作りましょう。彼女は12才という設定です。人間関係をうまく動かしてくれるのは、いつも年上の女性です。
Hanako.h
typedef struct HanakoStruct Hanako; extern Hanako *Hanako_create(); extern void Hanako_destroy(Hanako *hanako);
Hanako.c
typedef struct HanakoStruct {
Chairperson interface;
Taro *taro;
uint16_t age;
} HanakoStruct;
static void organizeClass(Chairperson *chair) {
Hanako *hanako = (Hanako*)chair;
Taro_enjoyWithAllClassmates(hanako->taro);
}
Hanako *Hanako_create() {
Hanako *hanako = (Hanako*)malloc(sizeof(Hanako));
hanako->interface.organizeClass = organizeClass;
hanako->taro = Taro_create();
hanako->age = 12;
return hanako;
}
void Hanako_destroy(Hanako *hanako) {
Taro_destroy(hanako->taro);
free(hanako);
}
Hanakoさんが居てくれるおかげで、Taroくんは何も変わる必要がありません。
Teacherを作る
最後にTeacherを作ります。TeacherはただChairpersonであるHanakoさんに仕事をお願いするだけです。
Teacher.h
extern void Teacher_doMain();
Teacher.c
void Teacher_doMain() {
Hanako *hanako = Hanako_create();
Chairperson_organizeClass((Chairperson*)hanako);
Hanako_destroy(hanako);
}