Реализация шаблона фабрики с использованием ANSI C - PullRequest
3 голосов
/ 08 июля 2010

Может кто-нибудь указать мне ссылку на то, как реализовать фабричный шаблон с использованием ANSI C? Если к этому добавится больше паттернов, это будет просто бонусом. Делать это в C ++ мне тривиально, но, поскольку в C нет классов и полиморфизма, я не совсем уверен, как это сделать. Я думал о том, чтобы иметь «базовую» структуру со всеми распространенными типами данных, а затем использовать пустые указатели и определять все общие части структур в том же порядке, что и в базовой структуре вверху? Или не гарантируется, что они останутся в памяти одинаковым образом?

Ответы [ 4 ]

6 голосов
/ 26 марта 2013

Шаблон фабрики также может быть реализован на C, предположим, что следующие операции определены вашим интерфейсом:

typedef int (*operations_1) (void *data);
typedef int (*operations_2) (void *data);

typedef struct impl_ops_t
{
    operations_1 op1;
    operations_2 op2;
} impl_ops_t;

Итак, чтобы иметь возможность получить экземпляр реализации, реализующий такой интерфейс, вы должны определитьструктура с данными и операциями, затем вы можете определить операцию создания, которая будет возвращать вам эту структуру и, возможно, также операции уничтожения:

typedef struct ctx_t
{
    void       *data;
    impl_ops_t *operations;
} ctx_t;

typedef ctx_t   (*create_handle)   (void);
typedef void    (*destroy_handle)  (ctx_t **ptr);

typedef struct factory_ops
{
    create_handle  create;
    destroy_handle destroy;
} factory_ops;

Вы также должны определить функцию, которая предоставляет вам фабричные методыВозможно, у вас должен быть способ получить правильную реализацию, исходя из ваших потребностей (возможно, это не простой параметр, как в примере ниже):

typedef enum IMPL_TYPE
{
    IMPL_TYPE_1,
    IMPL_TYPE_2
} IMPL_TYPE;
factory_ops* get_factory(int impl_type);

Так что он будет использоваться как:

main (...)
{
    factory_ops fact = get_factory(IMPL_TYPE_2);

    // First thing will be calling the factory method of the selected implementation
    // to get the context structure that carry both data ptr and functions pointer
    ctx_t *c = fact->create();

    // So now you can call the op1 function
    int a = c->operations->op1(c->data);
    // Doing something with returned value if you like..
    int b = c->operations->op2(c->data);
    // Doing something with returned value if you like..

    fact->destroy(&c);
    return 0;
}
1 голос
/ 08 июля 2010

C имеет функциональные указатели и структуры.Так что вы можете реализовать классы в C.

что-то вроде этого должно дать вам подсказку.

void class1_foo() {}
void class2_foo() {}

struct polyclass
{
    void (*foo)();
};

polyclass make_class1() { polyclass result; result.foo = class1_foo; return result; }
1 голос
/ 08 июля 2010

Здесь , внизу страницы, находится серия статей о шаблонах в C

0 голосов
/ 08 июля 2010

Фабричный шаблон - это объектно-ориентированный шаблон проектирования.

C не является объектно-ориентированным языком.

Поэтому я хотел бы спросить, какова ваша цель для Фабрики в C.

...