Which architectural approach can help prevent cyclic dependencies by decoupling components?

Get ready for your Object‑Oriented Programming Test. Use flashcards and multiple-choice questions. Each question includes hints and explanations. Prepare for your exam today!

Multiple Choice

Which architectural approach can help prevent cyclic dependencies by decoupling components?

Explanation:
Decoupling components by introducing an intermediary to coordinate interactions helps prevent cyclic dependencies. When components talk through a mediator or an event bus, they don’t hold direct references to each other. Instead, they interact with a shared channel or interface, which centralizes communication and isolates implementations. This breaks the bidirectional ties that often form cycles, letting parts evolve independently while still collaborating. A mediator coordinates requests and responses, keeping the calling components unaware of who handles the work. An event bus enables a publish–subscribe pattern, where components emit events and react to others’ events without needing to know who produced them. Both approaches reduce tight coupling and the risk of circular dependencies because the dependency graph points to the mediator or event system rather than directly between components. Merging all modules into one large package tends to increase, not reduce, interdependence, since everything remains tightly connected within a single boundary. Instantiating dependencies directly inside modules locks them to concrete implementations, creating strong ties and making it harder to break potential cycles. Depending on concrete implementations for flexibility is the opposite of decoupling, as it reinforces direct knowledge of and reliance on specific classes rather than abstract, interchangeable interfaces.

Decoupling components by introducing an intermediary to coordinate interactions helps prevent cyclic dependencies. When components talk through a mediator or an event bus, they don’t hold direct references to each other. Instead, they interact with a shared channel or interface, which centralizes communication and isolates implementations. This breaks the bidirectional ties that often form cycles, letting parts evolve independently while still collaborating.

A mediator coordinates requests and responses, keeping the calling components unaware of who handles the work. An event bus enables a publish–subscribe pattern, where components emit events and react to others’ events without needing to know who produced them. Both approaches reduce tight coupling and the risk of circular dependencies because the dependency graph points to the mediator or event system rather than directly between components.

Merging all modules into one large package tends to increase, not reduce, interdependence, since everything remains tightly connected within a single boundary. Instantiating dependencies directly inside modules locks them to concrete implementations, creating strong ties and making it harder to break potential cycles. Depending on concrete implementations for flexibility is the opposite of decoupling, as it reinforces direct knowledge of and reliance on specific classes rather than abstract, interchangeable interfaces.