Suggest an editImprove this articleRefine the answer for “What does "high-level modules should not depend on low-level modules" mean?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)The phrase **"high-level modules should not depend on low-level modules"** means that business logic (high level) should not directly depend on technical details (low level), such as the database, file system, logging, network clients, specific APIs, and so on. **Key point:** the high level should depend only on abstractions and contracts, while details plug in from outside, so the business logic stays stable and flexible.Shown above the full answer for quick recall.Answer (EN)ImageThe phrase **"high-level modules should not depend on low-level modules"** means that **business logic (high level) should not directly depend on technical details (low level)**, such as the database, file system, logging, network clients, specific APIs, and so on. In detail: ### 1. The high level is the business rules These are the classes and modules that define *what* the application does: - cost calculation, - order processing, - validation, - decision making. These modules should be stable and change rarely. ### 2. The low level is infrastructure and implementation details These are the classes responsible for *how*: - a specific database (MySQL, Postgres), - a specific HTTP library, - a specific logger, - a specific cache, - a data storage format. They change more often than business code. ### 3. The problem with a direct dependency If business logic depends on, say, `MySqlOrderRepository`, then: - switching to Postgres requires rewriting the business code; - replacing the HTTP library requires rewriting the business code; - writing a unit test is hard, because it contains concrete details inside. The business logic becomes fragile and hard to maintain. ### 4. DIP says: depend on abstractions Instead of: ```python class OrderService: def __init__(self): self.repo = MySqlOrderRepository() ``` It should be: ```python class OrderService: def __init__(self, repo: OrderRepositoryInterface): self.repo = repo ``` Now OrderService depends only on the **contract**, not on a concrete implementation. ### 5. Details should depend on abstractions, not the other way around MySqlOrderRepository should *implement* the interface: ```python class MySqlOrderRepository(OrderRepositoryInterface): ... ``` And it is the external system (the DI container, configuration) that decides which implementation to supply. ### 6. Benefit The high level becomes: - independent, - easy to test, - portable, - resistant to infrastructure changes. Summary: **"High-level modules should not depend on the low level" means that business logic should depend only on abstractions and contracts, not on concrete technical details. Details plug in from outside, while the business logic itself stays stable and flexible.**For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.