Factory Pattern in Elixir?

Neither Java nor C# existed when the GoF patterns were written down. It should also be noted that the GoF patterns book does not contain a Factory pattern. It contains two patterns that have the word Factory in them and two more that are factories in the modern sense but don’t contain the work Factory.

  • AbstractFactory
  • FactoryMethod
  • Builder
  • Prototype

Not all patterns are useful in all contexts, and you’re 100% right that different languages have different idioms and different needs.

Could you elaborate on that? One of the things I’m stuck on here is how I might have a package (say, something that gets published on Hex), and then how could I build it in a way that would open up customizations to users without requiring them to edit my code (which would be a big no-no)?

E.g. if I build out the mapping internally that handles the mapping of “condition-one” to SomePrivateModule.do_something() and “condition-two” to SomeOtherPrivateModule.do_something(), how could that mapping be extended via configuration so that a user could supply their own mapping so that “condition-three” maps to UserDefinedModule.do_something() ?

Thanks!

Protocols are what you’re looking for, I think. Elixir doesn’t know about all the enumerable data structures, but it defines a protocol that allows extension of your data structure to become enumerable, by doing

defimpl Enumerable, for: MyModule do
  # enum protocol implementation
end

Similarly if your code defines a behaviour, and the library has a function that knows how to dispatch to the appropriate behaviour callbacks, you can simply pass your module into the dispatcher and it can execute the relevant callbacks, having faith that they’ll be there.

1 Like

Just referencing modern day and what people would know it from. I’ve used factories way back since before C was standardized so I know it is very old pattern. ^.^;

This is the big key!!

You can put the ‘hardcoded’ map in the config files, then in the app anytime you need it access it via Application.get_env/2 and query it directly. You can even do that at compile-time to build up function matchers but by keeping it at run-time you can allow for it to be changed while the system is running to add/remove things to it without needing a hot code swap or reload. :slight_smile:

The configuration itself would just be a mapping of stringnames ↔ module names, or even full MFA’s if you want. :slight_smile:

Protocols are for dispatching on a type like a struct type so if you have that then absolutely yes, otherwise the plugin model is better (which you can also do via any arbitrary tag, like a string, with my ProtocolEx library ^.^).

2 Likes