Factories
Factories are objects which create your objects. They are useful in a number of circumstances:
- When your language is a poorly designed trash fire (chiefly C++), and compilers cannot agree on how creating an object is supposed to work.
- When creating an object may require or allow additional context now or in the future.
- When object creation needs to support versioning.
In some cases this is known as the Builder Pattern. Here is an example of a factory using the builder pattern:
thing_builder_t tb;
tb_start(tb);
tb_set_int(tb, tbPort, 8080); /* using a generic setter */
thing_t* obj = thing_create(tb);
/* fun stuff */
thing_destroy(obj);
Changing the parameters to a function can be a tricky proposition. However you can use the rest of the immortal ABI doctrine against the factory--since it's just an object with its own functions that can be added or removed without breaking anything.
We also have a tb_start
function defined here.
That could do any number of things:
- Embed the size of
thing_builder_t
as we understand it at compile time (the Microsoft method) - Embed a serial number as we understand it at compile time
- Embed a string identifier that we knew at compile time
Case Study: CLAP
The CLAP audio standard makes heavy use of the factory pattern and string identifiers. Factories are also used to produce other factories; with the exception of the "main" entry point to kick off access to the API.
It works a bit like this:
- You call an entry point function like
clap_init
- You provide a string representing the version of the API your program speaks
- It returns
nil
or a reference to the plugin factory - Further features repeat steps 2 and 3, but are requests made against the plugin factory instead.
Here is a trivial example in C:
notclap_t* = notclap_entry("com.example.not-clap/1");
if (notclap_t == NULL) goto failed;
notclap_cat_petter_t* =
notclap_t->get_plugin(notclap_t, "com.example.not-clap.cat-petter/1");
/* ... */
return 0
failed:
fprintf(stderr, "");
return 1
This looks a bit verbose because we are using C code. Better languages (Nim) allow you to pretty this up.