50
This code is blood sacrifice-dependent
(beehaw.org)
Post funny things about programming here! (Or just rant about your favourite programming language.)
Circular dependencies can be removed in almost every case by splitting out a large module into smaller ones and adding an interface or two.
In your bot example, you have a circular dependency where (for example) the bot needs to read messages, then run a command from a module, which then needs to send messages back.
This can be solved by making a command conform to an interface, and shifting the responsibility of registering commands to the code that creates the bot instance.
The
bot
module would expose theBot
class and aCommand
instance. Thecommand_foo
module would importBot
and export a class implementingCommand
.The
main
function would importBot
andCommandFoo
, and create an instance of the bot withCommandFoo
registered:It's a few more lines of code, but it has no circular dependencies, reduced coupling, and more flexibility. It's easier to write unit tests for, and users are free to extend it with whatever commands they want, without needing to modify the
bot
module to add them.