한 줄 요약하면, High-level class가 Low-level class에 의존하지 않도록 하라.
정도가 될 수 있다.
여기에서 High/Low-level class는 상속 관계를 의미한다기 보다 아래와 같이 정말 정성적인 의미로 사용된다.
예를 들어, 예산을 관리하는 Software를 아래와 같이 설계하였다고 가장해보자.
아래 구현은 필연적으로 BudgetManager
의 AddBudget
method가 MySQLDB
class에 의존적일 수 밖에 없다.
이는 MySQL 대신 MongoDB를 도입해야 하는 상황이 닥치는 경우를 생각해보면 쉽게 떠올릴 수 있다.
class MySQLDB
{
public:
void Insert(const Record& record);
void Update(const Record& record);
};
class BudgetManager
{
private:
MySQLDB mysql_db_;
public:
void AddBudget(const Budget& budget);
};
반면, 아래와 같이 High-level class가 Low-level class가 아닌 abstraction에 의존하도록 설계해준다면, DB가 변경되는 상황에서도 코드는 재사용성과 확장성을 유지할 수 있다.
이와 같이 High-level class가 Low-level class에 의존하지 않고 abstraction에만 의존하도록 하는 것이 Dependency Inversion의 핵심이다.
class DB
{
public:
virtual void Insert(const Record& record) = 0;
virtual void Update(const Record& record) = 0;
};
class MySQLDB : public DB
{
public:
void Insert(const Record& record);
void Update(const Record& record);
};
class MongoDB : public DB
{
public:
void Insert(const Record& record);
void Update(const Record& record);
};
class BudgetManager
{
private:
DB* db_;
public:
void AddBudget(const Budget& budget);
};