This is mostly a Functional Programming question rather than an Elixir one, but since I'm learning Elixir it would be nice if someone can answer it using that language. Even so, if someone wants to give a more general answer it'll be appreciated.
I'm an OO programmer myself and I can't wrap my head around how to change the behavior of a component based on a configuration file (for example).
Example: I have an application that loads/saves users from a database. In a production environment, I want my users to be saved and retrieved from a MongoDB database, while in development and testing I want to use an in-memory map. If I was programming given system in an OO language (Lets say Java), I would simply make an Interface named "UserRepository" with 2 implementations: "MemoryUserRepository" and "MongoDBUserRepository". I would then instantiate the corresponding Repository based on a configuration file (or hardcoding it, it doesn't matter) at startup and right after it, all the objects that interact with the Repository will never know its implementation (they will use a repository, but will never care if it's in memory or in mongo). That gives me the ability to create as many implementations as I want and the only thing I need to do to change the behavior of the system is instantiate the implementation that I want to use.
I want the same behavior but in Elixir (let's use the same example). Since it's not an Object Oriented language I can't use the above approach. Obviously I want it to be extensible (I could easily pass a String with the type of repository I want to use in each call and use pattern matching to determine what behavior to use, but that doesn't scale well because every time I'll want to add an implementation I will have to look in every piece of code I'm pattern matching the type and add the new implementation). What would be the best approach to achieve this?
Thanks in advance!