/* Copyright(C) 2009 Yoshinori Oota All rights reserved. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum COMPONENT_TYPE { LEAF ,COMPOSITE };
struct Component;
void indent(int n);
/* ComponentList */
struct ComponentList {
struct Component* component_;
struct ComponentList* next_;
};
struct ComponentList* New_ComponentList(struct Component* component);
void Delete_ComponentList(struct ComponentList* list);
/* Component Interface */
struct Component {
char* id_;
enum COMPONENT_TYPE type_;
struct ComponentList* child_top_;
struct ComponentList* child_last_;
void (*add)(struct Component* pthis, struct Component* child);
void (*print)(struct Component* pthis, int n);
struct Component* (*getComponentById)(struct Component* pthis, const char* id);
};
struct Component* New_Component(enum COMPONENT_TYPE type ,const char* c_id);
void Delete_Component(struct Component* component);
void Leaf_print(struct Component* pthis, int n);
void Leaf_add(struct Component* pthis, struct Component* child);
struct Component* Leaf_getComponentById(struct Component* pthis, const char* id);
void Composite_print(struct Component* pthis, int n);
void Composite_add(struct Component* pthis, struct Component* child);
struct Component* Composite_getComponentById(struct Component* pthis, const char* id);
/* Builder Interface */
struct Builder {
struct Component* root_;
struct Component* curComposite_;
struct Component* (*GetResult)(struct Builder* pthis);
};
struct Builder* New_Builder();
void Delete_Builder(struct Builder* builder);
struct Component* Builder_GetResult(struct Builder* pthis );
/* protected 属性のメソッドはインターフェースから外し、*/
/* メソッドの存在を隠蔽する */
void Builder_protected_BuildLeaf (struct Builder* pthis ,const char* id);
void Builder_protected_BuildComposite (struct Builder* pthis ,const char* id);
void Builder_protected_ChangeCurrent (struct Builder* pthis ,const char* id);
/* ComponentList Implementation */
struct ComponentList* New_ComponentList(struct Component* component) {
struct ComponentList* list = NULL;
list = (struct ComponentList*)malloc(sizeof(struct ComponentList));
list->component_ = component;
list->next_ = NULL;
return list;
}
void Delete_ComponentList(struct ComponentList* list) {
struct ComponentList* tmp = NULL;
if (list == NULL) {
return;
}
while (list != NULL) {
tmp = list->next_;
free(list);
list = tmp;
}
return;
}
/* Component Class Implementation */
struct Component* New_Component(enum COMPONENT_TYPE type ,const char* id) {
struct Component* component = NULL;
char* buf = NULL;
component = (struct Component*)malloc(sizeof(struct Component));
buf = (char*)malloc(sizeof(strlen(id)+1));
strcpy(buf, id);
component->id_ = buf;
component->type_ = type;
component->child_top_ = NULL;
component->child_last_ = NULL;
switch(type) {
case LEAF:
component->add = &Leaf_add;
component->print = &Leaf_print;
component->getComponentById = &Leaf_getComponentById;
break;
case COMPOSITE:
component->add = &Composite_add;
component->print = &Composite_print;
component->getComponentById = &Composite_getComponentById;
break;
}
return component;
}
void Delete_Component(struct Component* component) {
if (component == NULL) {
return;
}
if (component->type_ == COMPOSITE) {
struct ComponentList* cur = NULL;
cur = component->child_top_;
while (cur != NULL) {
Delete_Component(cur->component_);
cur = cur->next_;
}
Delete_ComponentList(component->child_top_);
}
free(component);
component = NULL;
return;
}
void Leaf_add(struct Component* pthis, struct Component* child) {
return; /* No operation */
}
void Leaf_print(struct Component* pthis ,int n) {
indent(n);
printf("- %s\n" ,pthis->id_);
return;
}
struct Component* Leaf_getComponentById(struct Component* pthis ,const char* id) {
return NULL;
}
void Composite_add(struct Component* pthis, struct Component* child) {
struct Component* cur = NULL;
struct ComponentList* list = NULL;
list = (struct ComponentList*)malloc(sizeof(struct ComponentList));
list->component_ = child;
list->next_ = NULL;
if (pthis->child_top_ == NULL) {
pthis->child_top_ = list;
pthis->child_last_ = list;
} else {
pthis->child_last_->next_ = list;
pthis->child_last_ = list;
}
return;
}
void Composite_print(struct Component* pthis ,int n) {
struct Component* component = NULL;
struct ComponentList* cur = NULL;
indent(n);
printf("+ %s\n" ,pthis->id_);
cur = pthis->child_top_;
while (cur != NULL) {
++n;
component = cur->component_;
component->print(component, n);
--n;
cur = cur->next_;
}
return;
}
struct Component* Composite_getComponentById(struct Component* pthis ,const char* id) {
struct ComponentList* cur = NULL;
struct Component* component = NULL;
struct Component* target = NULL;
if (strcmp(id, pthis->id_) == 0) {
return pthis;
}
cur = pthis->child_top_;
while (cur != NULL) {
component = cur->component_;
target = component->getComponentById(component, id);
if (target != NULL) {
return target;
}
cur = cur->next_;
}
return NULL;
}
/* Builder Class Implementation */
struct Builder* New_Builder() {
struct Builder* builder = NULL;
builder = (struct Builder*)malloc(sizeof(struct Builder));
builder->root_ = New_Component(COMPOSITE, "ROOT");
builder->curComposite_ = builder->root_;
builder->GetResult = &Builder_GetResult;
return;
}
void Delete_Builder(struct Builder* builder) {
if (builder == NULL) {
return;
}
free (builder);
builder = NULL;
return;
}
void Builder_protected_BuildLeaf(struct Builder* pthis ,const char* id) {
struct Component* cur = NULL;
struct Component* leaf = NULL;
cur = pthis->curComposite_;
leaf = New_Component(LEAF, id);
cur->add(cur, leaf);
return;
}
void Builder_protected_BuildComposite(struct Builder* pthis ,const char* id) {
struct Component* cur = NULL;
struct Component* composite = NULL;
cur = pthis->curComposite_;
composite = New_Component(COMPOSITE, id);
cur->add(cur, composite);
return;
}
void Builder_protected_ChangeCurrent (struct Builder* pthis ,const char* id) {
struct Component* component = NULL;
struct Component* target = NULL;
component = pthis->root_;
target = component->getComponentById(component, id);
if (target != NULL) {
pthis->curComposite_ = target;
}
return;
}
struct Component* Builder_GetResult(struct Builder* pthis) {
return pthis->root_;
}
/* Director */
void Director_Construct (struct Builder* builder) {
Builder_protected_BuildLeaf(builder, "L1");
Builder_protected_BuildLeaf(builder, "L2");
Builder_protected_BuildComposite(builder, "A");
Builder_protected_ChangeCurrent(builder, "A");
Builder_protected_BuildLeaf(builder, "L3");
Builder_protected_BuildLeaf(builder, "L4");
return;
}
void indent(int n) {
while (n != 0) {
printf(" ");
--n;
}
return;
}
int main() {
struct Builder* builder = NULL;
struct Component* component = NULL;
builder = New_Builder();
Director_Construct(builder);
component = builder->GetResult(builder);
component->print(component, 0);
Delete_Component(component);
Delete_Builder(builder);
return 0;
}
|