학습
C++ C++의 디자인 원칙 (SOLID 등)
C++ C++의 디자인 원칙 (SOLID 등) — 고급
C++의 디자인 원칙 (SOLID 등)
1. 도입 (왜 배워야 하는가)
프로그래밍에서 코드의 품질과 유지보수성은 매우 중요합니다. 특히 팀 프로젝트나 대규모 시스템을 개발할 때, 디자인 원칙을 따르는 것은 코드의 가독성을 높이고, 버그를 줄이며, 새로운 기능을 추가할 때 발생하는 문제를 최소화하는 데 도움이 됩니다. 이를 통해 개발자는 더 나은 소프트웨어를 만들 수 있으며, 고객의 요구를 빠르게 충족할 수 있습니다.
디자인 원칙을 모른다면, 코드가 복잡해지고 가독성이 떨어지며, 수정이 어려워질 수 있습니다. 이는 결국 개발 시간의 증가와 비용의 상승으로 이어질 수 있습니다. 따라서 SOLID 원칙은 C++ 프로그래머에게 필수적으로 배워야 할 중요한 개념입니다.
2. 핵심 개념 설명
SOLID는 객체지향 프로그래밍의 다섯 가지 설계 원칙을 나타내며, 각 원칙은 다음과 같은 의미를 가집니다:
| 원칙 | 설명 |
|---|---|
| S - 단일 책임 원칙 (Single Responsibility Principle) | 클래스는 하나의 책임만 가져야 한다. |
| O - 개방-폐쇄 원칙 (Open/Closed Principle) | 클래스는 확장에 열려 있어야 하고, 수정에는 닫혀 있어야 한다. |
| L - 리스코프 치환 원칙 (Liskov Substitution Principle) | 자식 클래스는 부모 클래스의 자리를 대체할 수 있어야 한다. |
| I - 인터페이스 분리 원칙 (Interface Segregation Principle) | 클라이언트는 사용하지 않는 인터페이스에 의존하지 않아야 한다. |
| D - 의존관계 역전 원칙 (Dependency Inversion Principle) | 고수준 모듈은 저수준 모듈에 의존하면 안 된다. |
이러한 원칙들은 마치 레고 블록처럼, 각기 다른 조각들이 함께 모여 강력한 구조물을 형성하는 것과 같습니다. 각 원칙이 지켜질 때, 코드는 더욱 튼튼하고 유연하게 변할 수 있습니다.
3. 기본 코드 예제
단일 책임 원칙 (SRP) 코드 예제
#include <iostream>
#include <string>
class Report {
public:
void generateReport(const std::string& data) {
std::cout << "Report generated with data: " << data << std::endl;
}
};
class ReportPrinter {
public:
void printReport(const Report& report) {
std::cout << "Printing report..." << std::endl;
}
};
int main() {
Report report;
report.generateReport("Sales Data");
ReportPrinter printer;
printer.printReport(report);
return 0;
}
실행 결과:
Report generated with data: Sales Data
Printing report...
Report클래스는 보고서를 생성하는 책임을 가진다.ReportPrinter클래스는 보고서를 출력하는 책임을 가진다.- 이처럼 각 클래스가 하나의 책임만 가지므로, 유지보수가 용이하다.
4. 실전 활용 예제
예제 1: 쇼핑몰에서 장바구니 구현
#include <iostream>
#include <vector>
#include <string>
class Item {
public:
std::string name;
double price;
Item(std::string n, double p) : name(n), price(p) {}
};
class Cart {
private:
std::vector<Item> items;
public:
void addItem(const Item& item) {
items.push_back(item);
}
void displayItems() {
std::cout << "Items in Cart:" << std::endl;
for (const auto& item : items) {
std::cout << item.name << ": $" << item.price << std::endl;
}
}
};
int main() {
Cart cart;
cart.addItem(Item("Shirt", 19.99));
cart.addItem(Item("Pants", 39.99));
cart.displayItems();
return 0;
}
실행 결과:
Items in Cart:
Shirt: $19.99
Pants: $39.99
Item 클래스는 상품의 이름과 가격을 가진다.Cart 클래스는 장바구니의 아이템을 관리하고, 출력하는 책임을 가진다.5. 흔한 실수와 주의사항
실수 1: 단일 책임 원칙 위반
class Report {
public:
void generateReport(const std::string& data) {
// Generate report
}
void printReport() {
// Print report
}
};
// 위 코드는 Report 클래스가 두 가지 책임을 가짐
Report 클래스와 ReportPrinter 클래스를 분리하여 각 클래스에 하나의 책임을 부여해야 한다.실수 2: 의존관계 역전 원칙 위반
class Database {
public:
void saveData() {
// Save data to the database
}
};
class User {
private:
Database db; // 의존성 주입이 없음
public:
void saveUser() {
db.saveData();
}
};
// 위 코드는 User 클래스가 Database에 강하게 결합되어 있음