5

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?

1

4 Answers 4

9

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; } 
Sign up to request clarification or add additional context in comments.

2 Comments

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?
In order to understand the reasons, I would recommend you to try to implement such a factory pattern without using function pointer
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; } 

Comments

1

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

Comments

-1

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.

7 Comments

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 - 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)?
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.
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.
@Justin, All that is possible to achieve using C. Take a look at this question for example; stackoverflow.com/questions/415452/object-orientation-in-c/…. 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 =)
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.