본문 바로가기

[게임 개발자를 위한 C++ 문법] 객체지향적 설계

@iamrain2025. 8. 21. 16:35

대부분의 라이브러리 및 오픈소스는 객체지향적으로 설계되어 있다.

좋은 설계로 구현된 코드는 개발 시간을 단축하고 기능 변경에 유연하게 대응할 수 있다.

 

응집도

클래스 또는 모듈 내부의 구성 요소들이 얼마나 밀접하게 관계되어 있는지를 나타내는 것을 응집도라고 한다.

클래스 내부에 관련 없는 기능들이 포함되어 있으면, 변경이 자주 발생하고 확장하기 어렵다.

 

응집도가 낮은 경우로 서로 관련 없는 기능들이 하나의 클래스에 포함된 경우가 있다.

응집도가 높은 경우는 서로 관련 있는 모듈들만 하나의 클래스에 있는 경우다.

 

결합도

결합도는 모듈 또는 클래스 간의 의존성을 말한다. 일반적으로 결합도가 낮을수록 좋은 코드다.

결합도가 높으면 모듈 간 의존성이 강해져서 하나의 모듈이 변경되면 다른 모듈도 영향을 받게 된다.

 

결합도를 낮추기 위해서는 인터페이스를 활용하는 방법이 있다.

#include <iostream>
#include <memory>

using namespace std;

// 공통 인터페이스 정의
class Engine {
public:
    virtual void start() = 0;
    virtual ~Engine() = default;
};

// DieselEngine 구현
class DieselEngine : public Engine {
public:
    void start() {
        cout << "Diesel Engine started" << endl;
    }
};

// 새로운 ElectricEngine 구현
class ElectricEngine : public Engine {
public:
    void start() {
        cout << "Electric Engine started silently" << endl;
    }
};

// Car 클래스는 Engine 인터페이스에만 의존
class Car {
private:
    unique_ptr<Engine> engine;

public:
    Car(unique_ptr<Engine> eng) : engine(move(eng)) {}

    void startCar() {
        engine->start();
        cout << "Car started" << endl;
    }
};

int main() {
    // DieselEngine을 사용하는 경우
    auto dieselEngine = make_unique<DieselEngine>();
    Car dieselCar(move(dieselEngine));
    dieselCar.startCar();

    // ElectricEngine을 사용하는 경우
    auto electricEngine = make_unique<ElectricEngine>();
    Car electricCar(move(electricEngine));
    electricCar.startCar();

    return 0;
}

 

SOLID 원칙

객체지향 프로그래밍을 위한 원칙으로 `SOLID` 원칙이라는 것이 있다.

이는 객체지향 설계에서 유지보수성과 확장성을 높이기 위한 5가지 원칙을 의미한다.

단일 책임 원칙(SRP)

Single Responsibility Principle, SRP는 클래스는 하나의 책임만 가져야 한다는 원칙이다.

클래스는 변경 이유를 하나만 가져야 하며, 특정 기능이나 역할을 수행하는데 집중해야 한다는 말이다.

개방 폐쇄 원칙(OCP)

Open-Closed Principle, OCP는 객체는 확장에 대해서 개방적이고 수정에 대해서 폐쇄적이어야 한다는 원칙이다.

기존 코드의 변경을 최소한으로 하면서 새로운 기능을 추가할 수 있도록 설계해야 한다는 말이다.

리스코프 치환 원칙(LSP)

Liskov Substitution Principle, LSP는 자식 클래스는 언제나 부모 클래스를 대체할 수 있다는 원칙이다.

부모 클래스를 사용하는 코드가 자식 클래스로 대체되더라도 정상적으로 동작해야 한다는 말이다.

인터페이스 분리 원칙(ISP)

Interface Segregation Principle, ISP는 클라이언트에서 사용하지 않는 메서드는 사용해선 안 된다는 원칙이다.

하나의 거대한 인터페이스보다는 세분화된 인터페이스를 만들어 필요한 기능만 구현하도록 설계해야 한다는 말이다.

의존 역전 원칙(DIP)

Dependency Inversion Principle, DIP는 추상성이 높고 안정적인 고수준의 클래스는 구체적이고 불안정한 저수준의 클래스에 의존해서는 안된다는 원칙이다.

구체적인 구현에 의존하는 것이 아니라, 인터페이스나 추상 클래스 같은 추상화 계층을 두어 결합도를 낮추는 것이 좋다는 말이다.

iamrain
@iamrain :: Annals of Unreal

iamrain 님의 블로그 입니다.

공감하셨다면 ❤️ 구독도 환영합니다! 🤗

목차