There have been multiple accounts created with the sole purpose of posting advertisement posts or replies containing unsolicited advertising.

Accounts which solely post advertisements, or persistently post them may be terminated.

Korne127 ,
@Korne127@lemmy.world avatar

This is the one thing where my opinion might be highly unpopular, but I don’t see circular dependencies as something bad. If you write really structured modularised code, and just use the APIs of the different modules, it is completely fine to have different modules all depend on each other. At least in object oriented programming, using this approach that’s almost guaranteed to happen.
E.g. imagine a configuration module: Other modules need access to the configuration module to get the different entry values, but the configuration module needs access to other modules to change specific stuff if you change a configuration entry. Of course you could separate that module into one data part and one action part changing the data and doing stuff in other modules, but if you use many modules like that, this will just become even more complicated and lead to duplicated structures (e.g. a specific data tree plus the exact same tree for actions) which would be cleaner if it was directly in the same module.
Or a different example: An (e.g. discord) bot which is connected in one module, and both messages to the bot can lead to the module getting informations from other modules and actions in other modules can trigger the bot, leading to them depending on each other.

Elderos ,

It does not get more complicated to split your example. What gets more complicated is giving all sort of unrelated responsabilities to a single class, simply because it is the path of least resistance.

In your example, all you need is an extra module listening for configuration changes and reacting to it. This way you leave your context-specific logic out of your data model, no need for cyclic dependency. There are so many downsides to cyclic dependency, to justify it because splitting your logic is “too complicated” really isn’t a strong argument.

Korne127 ,
@Korne127@lemmy.world avatar

I honestly don’t see a single downside, as long as it’s modularised, maintainable and with clean APIs. And e.g. with a configuration module: The place where I’ve experienced this was a place where bigger parts of the configuration module were classes to build specific custom tree configurations. And if one module would just save what should happen at the change of each entry (and not save that with that entry), it would need to duplicate the whole structure and map it to the entries, which is ugly. It just makes sense to put those strongly related configurational things into one configuration module which provides an easy API (one method for changing and one for retrieving a config element after constructing it and adding other modules).

Elderos , (edited )

What you seem to be describing is one big class with lots of responsabilities, and not circular dependency. Personally, I don’t think it is ideal, and I don’t know about your specific case so I could be wrong, but I have never seen a legit case for bloated classes. That being said, making a big class is still much better than splitting it into inter-dependant classes. Classes that know each other are so cohesive that they might as well be the same class anyway.

To add onto the circular dependency problem, it is not just about readability and cognitive load (though there is some of that), but cyclic dependencies actively break things, and make it much harder to manage the lifecycle of a program. No dependency injection, poor memory management, long compile times. It is a huge hack, and I understand that you think it can be the proper solution sometime, but it is really just a bad thing to do, and it will bite you some day. And I am assuming here that you’re using a language that is friendly, in some languages you won’t even compile or run past a certain point, and good luck cleaning up that mess.

edit: replaced “module” with “class” for consistency

eth0p ,

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.

<pre style="background-color:#ffffff;">
<span style="color:#323232;">    v-----------
</span><span style="color:#323232;">  bot    command_foo
</span><span style="color:#323232;">    -----------^
</span>

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.

<pre style="background-color:#ffffff;">
<span style="color:#323232;">    main <---
</span><span style="color:#323232;">    ^        
</span><span style="color:#323232;">    |          
</span><span style="color:#323232;">    bot ---> command_foo
</span>

The bot module would expose the Bot class and a Command instance. The command_foo module would import Bot and export a class implementing Command.

The main function would import Bot and CommandFoo, and create an instance of the bot with CommandFoo registered:

<pre style="background-color:#ffffff;">
<span style="color:#323232;">// bot module
</span><span style="color:#323232;">export interface Command {
</span><span style="color:#323232;">    onRegister(bot: Bot, command: string);
</span><span style="color:#323232;">    onCommand(user: User, message: string);
</span><span style="color:#323232;">}
</span><span style="color:#323232;">
</span><span style="color:#323232;">// command_foo module
</span><span style="color:#323232;">import {Bot, Command} from "bot";
</span><span style="color:#323232;">export class CommandFoo implements Command {
</span><span style="color:#323232;">    private bot: Bot;
</span><span style="color:#323232;">
</span><span style="color:#323232;">    onRegister(bot: Bot, command: string) {
</span><span style="color:#323232;">        this.bot = bot;
</span><span style="color:#323232;">    }
</span><span style="color:#323232;">
</span><span style="color:#323232;">    onCommand(user: User, message: string) {
</span><span style="color:#323232;">        this.bot.replyTo(user, "Bar.");
</span><span style="color:#323232;">    }
</span><span style="color:#323232;">}
</span><span style="color:#323232;">
</span><span style="color:#323232;">// main
</span><span style="color:#323232;">import {Bot} from "bot";
</span><span style="color:#323232;">import {CommandFoo} from "command_foo";
</span><span style="color:#323232;">
</span><span style="color:#323232;">let bot = new Bot();
</span><span style="color:#323232;">bot.registerCommand("/foo", new CommandFoo());
</span><span style="color:#323232;">bot.start();
</span>

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.

russjr08 ,
@russjr08@outpost.zeuslink.net avatar

5? Those are rookie numbers, gotta pump up those dependency graphs!

jungekatz ,

Well i fell for it already and now there is no going back 😨

TheSaneWriter ,
@TheSaneWriter@lemmy.thesanewriter.com avatar

Satan has created a library that runs as efficiently as possible and covers every possible use case, and all we need to do to get access is sacrifice 1000 virgins. Do it for the cause.

BaldProphet ,
@BaldProphet@kbin.social avatar

Sacrifice 1000 programmers, got it

xuxebiko ,

Think maybe the project manager will fall for it?

Xeelee ,
@Xeelee@kbin.social avatar

Luckily, we have an endless supply of virgins to sacrifice. Nobody said they have to be female, right?

NegativeLookBehind ,
@NegativeLookBehind@kbin.social avatar

But then, who will maintain the code?

Xeelee ,
@Xeelee@kbin.social avatar

We'll outsource it to India.

PelicanPersuader OP ,
@PelicanPersuader@beehaw.org avatar

Better to use China, they’ve got plenty of excess virgins

bear_with_a_hammer ,

Nah, let’s start from US -> Virgin Islands

xuxebiko ,

only 5?

HeavyRust ,
@HeavyRust@lemm.ee avatar

Pentagram for demon summoning ⛤

GitProphet ,

5 interdependent modules? how sweet…

  • All
  • Subscribed
  • Moderated
  • Favorites
  • random
  • [email protected]
  • lifeLocal
  • goranko
  • All magazines