Интерфейс для работы с записями работника


Я хотел попробовать поэкспериментировать с беглом интерфейс дизайн в языке программирования С++. Вот почему я хочу спросить вас, уважаемые пользователи комментарий код, комментарии о том, как я реализовать этот простой записи сотрудника.

Обратите внимание, что для максимальной простоты, я прибегая к как простые данные в качестве возможных структур.

#include <stdio.h>
#include <assert.h>
/* if this weren't just an example I'd make a linked list */
#define MAX_EMPLOYEE_COUNT 10

/* global this pointer, there is no way around this */
void* this;

typedef struct Employee {
    struct Employee* (*set_salary)(int);
    struct Employee* (*set_employee_id)(int);
    char* name;
    int salary;
    int employee_id;
} Employee;

Employee* do_set_salary(int s)
{
    ((Employee*)this)->salary = s;
    return this;
}

Employee* do_set_employee_id(int id)
{
    ((Employee*)this)->employee_id = id;
    return this;
}

typedef struct Record {
    Employee* (*add_employee)(char*);
    Employee employees[MAX_EMPLOYEE_COUNT];
    int cnt;
} Record;

Employee* do_add_employee(char *n)
{
    Record* this_record = (Record*)this;
    assert(this_record->cnt < MAX_EMPLOYEE_COUNT);
    this_record->employees[this_record->cnt].set_salary = do_set_salary;
    this_record->employees[this_record->cnt].set_employee_id = 
        do_set_employee_id;
    this_record->employees[this_record->cnt].name = n;
    this = &this_record->employees[this_record->cnt];
    this_record->cnt++;
    return this;
}

void init_record(Record* r)
{
    r->cnt = 0;
    r->add_employee = do_add_employee;
}

Record* edit(Record* r)
{
    this = r;
    return r;
}

void print_record(Record* r)
{
    int i;
    for (i = 0; i < r->cnt; i++) {
        printf("%s, salary %d, id %d\n",
               r->employees[i].name,
               r->employees[i].salary,
               r->employees[i].employee_id);
    }
}

int main(void)
{
    Record record;
    init_record(&record);

    /* behold, fluent interface design! */
    edit(&record)->
        add_employee("Alice")->
        set_salary(1500)->
        set_employee_id(10201);

    edit(&record)->
        add_employee("Bob")->
        set_salary(2000)->
        set_employee_id(10202);

    print_record(&record);

    return 0;
}


931
8
задан 24 ноября 2011 в 02:11 Источник Поделиться
Комментарии
1 ответ

Я бы бросить редактировать функцию и сделать add_employee точки входа в API. Я написал ряд плавных API в C++ и обнаружил, что разместив необходимые аргументы (например, ФИО сотрудника) в записи API с точки бесценный. С точки зрения использования, что-то вроде:

int main(void) {
Record db;
init_record(&db);
add_employee_to(&db, "Bob")
->having_salary(2000)
->with_id(10202);
return 0;
}

Цель API, это создать нового сотрудника и добавить их, так что точка входа. Если вы не можете иметь действительные записи о сотруднике с такой фамилией, то это будет первоклассный параметр точки входа. Не уверен насчет требований, поэтому она может иметь смысл для ID должен быть обязательный параметр, а также. Я также изменил имена, чтобы сделать их более свободно™.

3
ответ дан 25 ноября 2011 в 02:11 Источник Поделиться