SOLID 원칙 (SOLID Principles)
SOLID 원칙은 코드를 더 깨끗하고 유지보수하기 쉬우며 확장 가능하게 만들기 위한 5가지 핵심 가이드라인입니다 [1]. Unity 개발 환경에서 이 원칙들을 어떻게 적용할 수 있는지 알아보겠습니다.
1. 단일 책임 원칙 (Single-responsibility principle, SRP)
"하나의 클래스는 변경해야 할 이유가 오직 하나여야 합니다." [2]
- 핵심 개념: 각 모듈, 클래스, 함수는 한 가지 책임만 지며, 해당 로직만 캡슐화해야 합니다 [2].
- Unity 예시: 거대한
Player스크립트를 만드는 대신MeshFilter,Renderer,Rigidbody처럼 기능을 쪼개어 여러 컴포넌트로 구성하십시오 [2, 3]. - 장점: 가독성이 좋아지고, 코드를 수정하거나 재사용하기 훨씬 쉬워집니다 [4, 5].
2. 개방-폐쇄 원칙 (Open-closed principle, OCP)
"클래스는 확장에 대해서는 열려 있어야 하지만, 수정에 대해서는 닫혀 있어야 합니다." [6]
- 핵심 개념: 기존 소스 코드를 직접 수정하지 않고도 새로운 기능을 추가할 수 있도록 구조화해야 합니다 [6].
- 적용 방법: 추상 클래스(Abstract class)나 인터페이스(Interface)를 활용하십시오. 예를 들어,
AreaCalculator클래스가 각 도형의 넓이를 직접 계산하는 대신,Shape추상 클래스에CalculateArea메서드를 두고 각 도형 클래스가 이를 구현하게 합니다 [7-9]. - 장점: 새로운 요구사항이 생겨도 기존의 검증된 코드를 건드리지 않아도 되므로 버그 발생 위험이 줄어듭니다 [10].
3. 리스코프 치환 원칙 (Liskov substitution principle, LSP)
"파생 클래스는 반드시 기반 클래스를 대체할 수 있어야 합니다." [11]
- 핵심 개념: 상속 관계에서 자식 클래스는 부모 클래스의 기능을 깨뜨리지 않고 그대로 수행할 수 있어야 합니다 [11].
- 주의 사항: 만약 하위 클래스에서 특정 메서드를 구현하지 않고 비워두거나
NotImplementedException을 던진다면, 이는 LSP를 위반한 것입니다 [12, 13]. - Unity 예시: 모든 운송 수단을
Vehicle로 상속받기보다, 회전이 불가능한 '기차'와 회전이 가능한 '자동차'를 위해ITurnable,IMovable인터페이스로 기능을 분리하여 합성(Composition)을 사용하십시오 [14-16].
4. 인터페이스 분리 원칙 (Interface segregation principle, ISP)
"어떤 클라이언트도 사용하지 않는 메서드에 의존하도록 강제해서는 안 됩니다." [17]
- 핵심 개념: 거대한 인터페이스 하나보다는 작고 구체적인 인터페이스 여러 개가 낫습니다 [17].
- 적용 방법:
IUnitStats라는 거대 인터페이스 대신IDamageable,IMovable,IExplodable등으로 잘게 쪼개십시오 [18, 19]. - 장점: 클래스가 꼭 필요한 기능만 구현하게 되어 시스템 간의 결합도가 낮아집니다 [18, 20].
5. 의존 역전 원칙 (Dependency inversion principle, DIP)
"고수준 모듈은 저수준 모듈에서 직접 가져오지 말아야 하며, 둘 다 추상화에 의존해야 합니다." [20]
- 핵심 개념: 클래스 간의 직접적인 연결(결합)을 최소화하고 인터페이스와 같은 추상화 계층을 사이에 두어야 합니다 [21, 22].
- Unity 예시:
Switch클래스가 특정Door클래스를 직접 참조하는 대신,ISwitchable인터페이스를 참조하게 하십시오. 이렇게 하면 스위치로 문뿐만 아니라 조명이나 로봇 등 무엇이든 작동시킬 수 있습니다 [23-26]. - 장점: 코드의 재사용성이 높아지고 시스템이 유연해집니다 [26, 27].
Tip: SOLID 원칙은 절대적인 규칙이 아니라 가이드라인입니다 [28]. 프로젝트의 규모와 복잡도에 맞춰 "단순함(KISS 원칙)"과 균형을 맞추는 것이 중요합니다 [29, 30].
