4

Can anyone point me to a reference on how to implement the factory pattern using ANSI C? If more patterns are covered to that would just be a bonus. Doing this in C++ i trivial for me, but since C does not have classes and polymorphism I'm not quite sure how to do it. I was thinking about having a "base" struct with all the common data types and then using void pointers, and defining all the common parts of the structs in the same order as in the base struct at the top? Or is it not guaranteed that they end up in the same way in memory?

Deduplicator
  • 41,806
  • 6
  • 61
  • 104
inquam
  • 11,960
  • 14
  • 53
  • 95
  • 1
    You can do polymorphism in C, but it's not pretty. See these questions: http://stackoverflow.com/questions/524033/how-can-i-simulate-oo-style-polymorphism-in-c http://stackoverflow.com/questions/351733/can-you-write-object-oriented-code-in-c http://stackoverflow.com/questions/415452/object-orientation-in-c – Adam Rosenfield Jul 08 '10 at 14:27

4 Answers4

7

Factory pattern can be implemented in C also, suppose the following are the operations that your interface defines:

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;

So, to be able to get an implementations instance that implements such interface, you should define a structure with both data and operations, then you can define the create operation that will return to you that structure and probably a destroy operations also:

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;

You should also define a function that provides you the factory methods, maybe you should have a way to get the right implementation basing on your needs (probably not a simple parameter like in the example below):

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

So it will be used like:

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;
}
Giordano
  • 291
  • 2
  • 5
  • Congrats! This is a nice and neat example! Thanks! – kazbeel Sep 08 '14 at 10:32
  • I'm new to factory pattern and I writes C only. This example is very counterintuitive to me. Why not just calling `operations_1` and `operations_2` directly? Is there any benefit to use pointer to pointer to function? – Andy Lin Jan 10 '21 at 15:35
  • In order to understand the reasons, I would recommend you to try to implement such a factory pattern without using function pointer – Giordano Jan 18 '21 at 06:35
1

C have function pointers and structs. So you can implement classes in C.

something like this should give you a clue.

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

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

polyclass make_class1() { polyclass result; result.foo = class1_foo; return result; }
Tom
  • 39,851
  • 25
  • 129
  • 164
yatagarasu
  • 502
  • 5
  • 13
1

Here, at the bottom of the page, is a series of articles about patterns in C

pcent
  • 1,773
  • 2
  • 13
  • 17
0

The Factory pattern is an Object-Oriented design pattern.

C is not an Object-Oriented language.

Therefore, I would question what your goal is for a Factory in C.

Justin Niessner
  • 229,755
  • 35
  • 391
  • 521
  • That a module I'm about to build is really suitable for the factory design-patten. But the company has a strict policy of only using ansi C. – inquam Jul 08 '10 at 14:26
  • 1
    @inquam - Understandable, but could you maybe give us an example of what you want the factory for (since normally a Factory is used to create an instance of an Interface backed by different class implementations)? – Justin Niessner Jul 08 '10 at 14:28
  • I know and this is what I want... But have to struggle with the limitations of C. Let's say you build a system that will scan for viruses in files and report the findings. There are many different ways, and more might come up in the future to, detect the different viruses. But the reporting part for all these are the same. If I could have a way to make the "base" with data structure for holding report data etc in a similar fashion, all different "scanners" could run through the same report functions. But the actual work they to to scan could be different. – inquam Jul 08 '10 at 14:44
  • 3
    I disagree. Object orientation is a paradigm, a paradigm which can be realised using C. I'm not saying that it's a good idea though. – manneorama Jul 08 '10 at 16:18
  • @manneorama - Object Oriented programming is defined as a language supporting three basic concepts: inheritance, polymorphism, and encapsulation. Without inheritance and polymorphism...C doesn't qualify. – Justin Niessner Jul 08 '10 at 16:27
  • 4
    @Justin, All that is possible to achieve using C. Take a look at this question for example; http://stackoverflow.com/questions/415452/object-orientation-in-c/415536#415536. Now, I'm not arguing that C is designed for being used in an object oriented manner and I'm not saying that it should be used in such a way, in place of a maybe more capable language. I'm saying that if someone, for some reason, wants to do it, it is possible and can be done. With substantial effort and very little gain =) – manneorama Jul 08 '10 at 19:47