SOLID 원칙 이해: 종속성 반전
하지만 이제 최종 보스를 만날 시간입니다.
DIP aka Dependency Inversion Principle
SOLID 보스의 최종 원칙.
장비를 갖추고 마나 물약을 마시고 전투를 준비하십시오.
목차
의존성 반전 원리란?
Let's google that.
We get this:
The Dependency Inversion Principle (DIP) states that high-level modules should not depend on low-level modules; both should depend on abstractions. Abstractions should not depend on details. Details should depend upon abstractions.
I get it, it sounds confusing.
But let's break this down:
- Client: Your main class/code that runs the high-level module.
- High-Level Modules: Interface/Abstraction that your client uses.
- Low-Level Modules: Details of your interfaces/abstraction.
What it basically says that imagine you have a car and your different components are:
- Client: You as the person driving the car.
- High-Level Modules: The steering wheel and the gas/brake peddles.
- Low-Level Modules: Engine
Abstractions don't depend on details.
For me, it doesn't matter whether my engine has changed or not, I still should be able to drive my car the same way.
Details should depend upon abstractions.
I would not want an engine that causes the brake to double the speed.
간단한 예
Imagine you have a budget reporting system that reads from a database.
It will look something like this:
<?php
class BudgetReport {
public $database;
public function __construct($database)
{
$this->database = $database;
}
public function open(){
$this->database->get();
}
public function save(){
$this->database->insert();
}
}
class MySQLDatabase {
// fields
public function get(){
// get by id
}
public function insert(){
// inserts into db
}
public function update(){
// update some values in db
}
public function delete(){
// delete some records in db
}
}
// Client
$database = new MySQLDatabase();
$report = new BudgetReport($database);
$report->open();
Everything works fine, but this code violates the dependency inversion principle because our high-level module BudgetReport
concretely depends on the low-level module MySQLDatabase
.
This also violates the open-closed principle because what if we wanted a different kind of database such as MongoDB?
We will have to change the BudgetReport
class to have if-else statements for it not to break.
To fix this is pretty simple, instead of concretely relying on the database class, we should use an abstraction. We will create a DatabaseInterface
which will implement any kind of database we need and finally we can inject our database through the constructor.
interface DatabaseInterface {
public function get();
public function insert();
public function update();
public function delete();
}
class MySQLDatabase implements DatabaseInterface {
// fields
public function get(){
// get by id
}
public function insert(){
// inserts into db
}
public function update(){
// update some values in db
}
public function delete(){
// delete some records in db
}
}
class MongoDB implements DatabaseInterface {
// fields
public function get(){
// get by id
}
public function insert(){
// inserts into db
}
public function update(){
// update some values in db
}
public function delete(){
// delete some records in db
}
}
class BudgetReport {
public $database;
public function __construct(DatabaseInterface $database)
{
$this->database = $database;
}
public function open(){
$this->database->get();
}
public function save(){
$this->database->insert();
}
}
// Client
$mysql = new MySQLDatabase();
$report_mysql = new BudgetReport($mysql);
$report_mysql->open();
$mongo = new MongoDB();
$report_mongo = new BudgetReport($mongo);
$report_mongo->open();
Now our BudgetReport
does not depend concretely on the database class but on its abstraction DatabaseInterface
. This approach also follows the open-closed principle because to add any new database we don't have to change the BudgetReport
class. We just need to add a new database class that implements the DatabaseInterface
.
왜 이 원칙을 따라야 합니까?
Because code that violates this principle may become too coupled together, and that makes the code hard to maintain, unreadable, and prone to side effects.
결론
In summary:
- The Dependency Inversion Principle (DIP) states that high-level modules should not depend on low-level modules; both should depend on abstractions. Abstractions should not depend on details. Details should depend upon abstractions.
- Code that doesn't follow this principle can be too coupled, which means you will have a hard time managing the project.
If you have any questions, leave them down in the comments section.
Reference
이 문제에 관하여(SOLID 원칙 이해: 종속성 반전), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/tamerlang/understanding-solid-principles-dependency-inversion-1b0f텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)