Reputation: 3218
What is the best practice to avoid circular dependencies? I had this problem with Javascript but it also applies to any other programming language.
For example I have this translationService.ts
module where whenever a locale is changed, I want to reload settings (so I need to import the settingsService.ts
. But in my settingsService.ts
I have a function reloadSettings
which uses the translationService
to translate the error message.
I guess you could say that the translationService
should not know anything about the settingsService
but how do you actually write the code to accomplish that?
translationService.ts
import { reloadSettings } from '@/services/settingsService.ts'
// When the locale is changed, we want to reload the settings
const changeLocale = (locale: string) => {
i18n.locale = locale
reloadSettings()
}
But in my settingsService.ts
I have a dependency on the translationService
in order to show the exception in the correct locale.
settingsService.ts
import settingsApi from '@/api/settingsApi.ts'
import { translate } from '@/services/translationService.ts'
const reloadSettings = () => {
try {
settingsStore.settings = settingsApi.getSettings()
} catch (error) {
console.log(
translate(error.message)
)
}
}
So I end up with circular dependencies where settingsService
depends on translationService
and translationService
depends on settingsService
settingsService -> translationService -> settingsService
Upvotes: 1
Views: 147
Reputation: 48314
In most cases like this you should avoid the two-way coupling by removing at least one dependency and replace it with indirect coupling
Take your example.
But in my settingsService.ts I have a function reloadSettings which uses the translationService to translate the error message.
Sounds correct, your translation service sounds to be in lower level. Keep this dependency as direct.
I have this translationService.ts module where whenever a locale is changed, I want to reload settings (so I need to import the settingsService.ts)
No, you don't have to have a direct dependency here.
You can easily introduce an event emitter that just emits a locale-changed event and the settings service just subscribes to the event.
There's no direct dependency, both depend on the event emitter but still they communicate through events.
Upvotes: 2