I’ve been using a function object design pattern for my Lobby system and it’s working well enough that I wanted to post about it.
The concept is very simple. Encapsulate the input and output parameters to a function, and the function call itself, in an object. This lets you manipulate a function call the same way you do objects.
Some useful things you can then do:
- Serialize them over the network
- Save them to disk
- Put them in a queue, for a test execution path
- Save them to call later
- Move the inputs and outputs around between threads
- Log what runs
- Perform operations on a set of function objects via the base class
- Give the user more functions by giving them more function objects from a class factory, making the system easy to extend.
So the lobby system exposes a large set of function objects. The user gets one from the class factory, with an identifier for what function to perform. The input parameters are filled in. They are serialized, processed remotely, and sent back. The user has all the contextual information because the input parameters are sent back as well as the output parameters. And a cool thing about this is the memory for function call lives on the internet. From the client’s point of view it is stateless. The client doesn’t have to track what is running.
It’s also useful for asynchronous operations.
In my case, rather than having a function pointer, the functor’s operation is in the functor itself (e.g. DoWork()). The needed parameters are passed to DoWork(), and operate on the database.