解释器模式(大话设计模式)C/C++版本
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <assert.h>
typedef struct Expression Expression;
typedef struct TerminalExpression TerminalExpression;
typedef struct AndExpression AndExpression;
typedef struct Context Context;
// 抽象表达式结构体
struct Expression
{
bool (*interpret)(struct Expression *, const char *);
};
// 终结符表达式结构体
struct TerminalExpression
{
struct Expression base;
char **infos;
size_t num_infos;
};
// 非终结符表达式结构体
struct AndExpression
{
struct Expression base;
struct Expression *smartCity;
struct Expression *smartPerson;
};
// 上下文结构体
struct Context
{
struct Expression *smartAndExpr;
};
bool and_interpret(struct Expression *self, const char *info);
bool terminal_interpret(struct Expression *self, const char *info);
// 创建终结符表达式
struct TerminalExpression *create_terminal_expression(char **datas, size_t num_datas)
{
struct TerminalExpression *expr = malloc(sizeof(struct TerminalExpression));
expr->base.interpret = terminal_interpret;
expr->infos = malloc(num_datas * sizeof(char *));
expr->num_infos = num_datas;
size_t i;
for (i = 0; i < num_datas; i++)
{
expr->infos[i] = strdup(datas[i]);
}
return expr;
}
// 创建非终结符表达式
struct AndExpression *create_and_expression(struct Expression *city, struct Expression *person)
{
struct AndExpression *expr = malloc(sizeof(struct AndExpression));
expr->base.interpret = and_interpret;
expr->smartCity = city;
expr->smartPerson = person;
return expr;
}
// 终结符表达式的解释操作
bool terminal_interpret(struct Expression *self, const char *info)
{
struct TerminalExpression *expr = (struct TerminalExpression *)self;
size_t i;
for (i = 0; i < expr->num_infos; i++)
{
if (strcmp(info, expr->infos[i]) == 0)
{
return true;
}
}
return false;
}
// 非终结符表达式的解释操作
bool and_interpret(struct Expression *self, const char *info)
{
struct AndExpression *expr = (struct AndExpression *)self;
char *buffer = strdup(info);
char *token = strtok((char *)buffer, "的");
bool cityMatched = false;
bool personMatched = false;
while (token != NULL)
{
if (!cityMatched && expr->smartCity->interpret(expr->smartCity, token))
{
cityMatched = true;
}
else if (!personMatched && expr->smartPerson->interpret(expr->smartPerson, token))
{
personMatched = true;
}
else
{
if (buffer)
free(buffer);
return false;
}
token = strtok(NULL, "的");
}
if (buffer)
free(buffer);
return cityMatched && personMatched;
}
// 创建上下文
struct Context *create_context()
{
struct Context *ctx = malloc(sizeof(struct Context));
char *citys[] = {"成都", "临沂"};
char *persons[] = {"老人", "儿童"};
struct TerminalExpression *cityExpr = create_terminal_expression(citys, sizeof(citys) / sizeof(citys[0]));
struct TerminalExpression *personExpr = create_terminal_expression(persons, sizeof(persons) / sizeof(persons[0]));
struct AndExpression *andExpr = create_and_expression(&cityExpr->base, &personExpr->base);
ctx->smartAndExpr = &andExpr->base;
return ctx;
}
// 上下文的解释操作
void context_is_free(struct Context *ctx, const char *info)
{
if (ctx->smartAndExpr->interpret(ctx->smartAndExpr, info))
{
printf("%s , 您本次乘车免费\n", info);
}
else
{
printf("%s , 您本次乘车扣费2¥\n", info);
}
}
// 销毁终结符表达式
void destroy_terminal_expression(struct TerminalExpression *expr)
{
size_t i;
for (i = 0; i < expr->num_infos; i++)
{
free(expr->infos[i]);
}
free(expr->infos);
free(expr);
}
// 销毁非终结符表达式
void destroy_and_expression(struct AndExpression *expr)
{
destroy_terminal_expression((struct TerminalExpression *)expr->smartCity);
destroy_terminal_expression((struct TerminalExpression *)expr->smartPerson);
free(expr);
}
// 销毁上下文
void destroy_context(struct Context *ctx)
{
struct AndExpression *andExpr = (struct AndExpression *)ctx->smartAndExpr;
destroy_and_expression(andExpr);
free(ctx);
}
int main()
{
struct Context *bus = create_context();
char *passengers[] = {"成都的老人", "成都的年轻人", "成都的儿童", "临沂的老人", "临沂的年轻人", "临沂的儿童"};
size_t i;
for (i = 0; i < sizeof(passengers) / sizeof(passengers[0]); i++)
{
context_is_free(bus, passengers[i]);
}
destroy_context(bus);
return 0;
}