게임 개발자를 위한 C++ 문법

게임 개발자를 위한 C++ 문법 / 2-4

jh009 2026. 5. 15. 15:12

객체지향적 설계

객체지향적으로 코드를 구현해야되는 이유

1. 대부분 라이브러리 및 오픈소스는 객체지향적으로 설계되어 있음 → 이해하면 더 깊이 있는 학습이 가능

2. 좋은 설계로 구현된 코드는 개발 시간을 단축할 수 있음

3. 좋은 설계로 구현된 코드는 기능 변경에 유연하게 대응할 수 있음


응집도

클래스 또는 모듈 내부의 구성 요소들이 얼마나 밀접하게 관련되어 있는지를 나타냄

 

응집도가 낮은 경우

서로 관련 없는 기능들이 하나의 클래스에 포함된 경우를 의미

 

1. 목적이 다른 기능이 섞여 있음

2. 하나의 클래스에 모든 기능이 집중되어 유지 보수가 어려움

 

응집도가 높은 경우

로 관련 있는 모듈들만 하나의 클래스에 있는 경우를 의미

 

1. 기능 변경이 필요할 때 특정 클래스만 수정하면 됨

2. 관련된 클래스 끼리 정보를 공유하여 코드의 구조가 명확해짐


결합도

  • 모듈 또는 클래스 간의 의존성
  • 일반적으로 결합도는 낮을수록 좋은 코드
  • 결합도가 높으면 각 모듈 간 의존성이 강해져, 하나의 모듈이 변경될 때, 다른 모듈도 영향을 받게 됨

SOLID 원칙

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

 

SOLID 원칙의 주요 목적

1. 유지보수성 및 확장성 향상 → 재사용성이 향상됨

2. 변경에 유연한 설계 제공


S. 단일 책임 원칙(SRP)

각 클래스는 하나의 책임만 가져야 한다는 원칙

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

 

잘못 적용된 예시)

student 클래스에 모든 메서드가 구현되버림

→ student 클래스에는 student 정보만 있는 것이 좋음

 

 

제대로 적용된 예시)

student 는 학생 정보만 담고 있고,

GradeCalculator 는 성적 계산

StudentPrinter 는 출력을 맡고 있음


O. 개방 폐쇄 원칙(OCP)

(다 이해하기 힘들면 이거라도 이해하기)

 

확장에는 열려 있어야 하고, 수정에는 닫혀있어야 한다는 개념

기존 코드를 최소한으로 변경하면서 새로운 기능을 추가할 수 있도록 설계해야 함

 

잘못 적용된 예시)

도형이 추가되면 메서드를 수정해야됨

→ 수정에 대해 모두 영향을 받음

→ 수정이 열려있음

 

제대로 적용된 예시)

도형이 추가되어도 class ShapeManager 의 코드는 수정되거나 영향을 받지 않음

→ 수정이 닫혀있음


l. 리스 코프 치환 원칙(LSP)

자식 클래스는 부모 클래스에서 기대되는 행동을 보장해야 함

 

객체지향 프로그래밍에서 다형성을 활용할 때,

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

 

이를 위해 자식 클래스는 부모 클래스의 동작을 일관되게 유지해야 함


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

클라이언트는 자신이 사용하지 않는 메서드에 의존하지 않아야 한다는 원칙

 

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

 

인터페이스로 분리해서 구현하라는 뜻

 

잘못 적용된 예시)

 

제대로 적용된 예시)


D. 의존 역전 원칙(DIP)

고수준 모듈은 저수준 모듈에 직접 의존하는 것이 아니라, 두 모듈 모두 추상화에 의존해야 함

 

고수준 모듈 → 인터페이스에 해당

저수준 모듈 → 인터페이스를 구현하는 클래스

 

구체적인 구현(저수준 모듈)에 의존하는 것이 아니라,

인터페이스나 추상 클래스 같은 추상화 계층을 두어 결합도를 낮추는 것이 좋은 설계

 

잘못 적용된 예시)

 

클래스 자체로 선언해버림 → 타입이 강하다고 표현

타입이 확정돼버림 → 다형성을 활용해서 구현 불가능함 

 

제대로 적용된 예시)

InputDevice만 상속받고 구현해주면 됨

OutputDevice도 마찬가지.

 

class Computer 에선 인터페이스를 활용 ( InputDevice* inputDevice; )

→ InputDevice 인터페이스로 구현한 어떤 장치가 와도 동작 가능

 

class Computer 내부에 인터페이스화(InputDevice* inputDevice;)를 해서 세부사항에 의존적이지 않고도 구현 가능