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); }