SOLID 객체 지향 설계 원칙
SOLID 객체 지향 설계 원칙
객체 지향 설계를 할 때 고려해야 할 가장 기본적이고 강력한 다섯 가지 원칙을 SOLID
라고 합니다.
이 원칙들을 통해 유지보수성과 확장성이 뛰어난 소프트웨어 구조를 만들 수 있습니다.
1. 단일 책임 원칙 (SRP, Single Responsibility Principle)
하나의 클래스는 단 하나의 책임만 가져야 한다.
- 하나의 클래스나 모듈은 오직 하나의 변경 이유만 가져야 합니다.
- 여러 책임을 한 클래스가 맡게 되면, 하나의 책임 변경이 다른 책임의 동작에 영향을 미칠 수 있습니다.
예시:
사용자 정보를 저장하고 출력하는 기능을 하나의 클래스에서 처리하기보다는, 저장과 출력을 각기 다른 클래스로 분리하는 것이 좋습니다.
2. 개방-폐쇄 원칙 (OCP, Open/Closed Principle)
소프트웨어 요소는 확장에는 열려 있어야 하고, 변경에는 닫혀 있어야 한다.
- 기존 코드를 수정하지 않고도 새로운 기능을 추가할 수 있어야 합니다.
- 인터페이스나 추상 클래스를 통해 유연한 설계가 가능합니다.
예시:
결제 방식이 바뀔 때 기존 PaymentProcessor
클래스를 수정하는 대신, CreditCardPayment
, PayPalPayment
같은 하위 클래스를 만들어서 확장할 수 있습니다.
3. 리스코프 치환 원칙 (LSP, Liskov Substitution Principle)
하위 타입은 상위 타입을 대체할 수 있어야 한다.
- 하위 클래스는 상위 클래스의 기능을 깨뜨리지 않고 그대로 사용할 수 있어야 합니다.
- “is-a” 관계가 성립하도록 설계해야 합니다.
예시:
Bird
라는 상위 클래스를 상속받은 Penguin
이 fly()
메서드를 가지고 있다면 문제가 생깁니다. 날 수 없는 펭귄은 Bird
의 행동을 따르지 않기 때문입니다.
4. 인터페이스 분리 원칙 (ISP, Interface Segregation Principle)
클라이언트는 자신이 사용하지 않는 메서드에 의존하지 않아야 한다.
- 하나의 범용 인터페이스보다는 역할에 따라 분리된 여러 개의 인터페이스가 바람직합니다.
- 불필요한 의존성을 줄일 수 있어 변경에 유연합니다.
예시:
Machine
인터페이스에 print()
, scan()
, fax()
가 모두 있는 것보다, Printer
, Scanner
, Fax
처럼 분리된 인터페이스가 더 바람직합니다.
5. 의존관계 역전 원칙 (DIP, Dependency Inversion Principle)
추상화에 의존해야지, 구체화에 의존하면 안 된다.
- 고수준 모듈은 저수준 모듈의 세부 구현이 아닌, 추상화된 인터페이스에 의존해야 합니다.
- 이를 통해 모듈 간 결합도를 낮출 수 있습니다.
예시:
OrderService
가 직접 MySQLDatabase
를 의존하는 대신, DatabaseInterface
를 통해 의존하게 만들고 구체 클래스는 외부에서 주입합니다.
🎯 SOLID 원칙은 하나하나 따로 적용하는 것보다, 전체적으로 조화롭게 사용하는 것이 중요합니다.
이 원칙들을 고려해 설계한 시스템은 유연하고, 테스트하기 쉬우며, 변경에 강한 구조를 가질 수 있습니다.