SOLID 란?
→ 객체지향 설계 시 지켜야 하는 설계 원칙 5가지를 줄여서 부름
- 시간이 지나도 유지보수와 확장이 용이한 시스템을 만들고자 할 때 적용하는 원칙
- 장점: 유연성, 재사용성, 유지보수성이 높아짐

1) 단일 책임 원칙 SRP
: 한 클래스는 하나의 책임만 가져야 하고 클래스를 변경하는 이유도 단 하나여야 한다.
- 지키지 않을 시, 한 책임의 변경에 의해서 다른 책임과 관련된 코드에 영향을 미칠 수 있음
- 유지보수가 매우 비효율적이게 됨
- 책임 = 기능
- 한 클래스가 수행할 수 있는 기능이 여러 개라면, 클래스 내부의 함수에서 결합도가 높아짐
- 응집도는 높고 결합도는 낮은 프로그램을 설계하는 것이 객체지향 설계의 핵심
- 책임을 잘게 쪼개어 분리시킬 필요가 있음
ex) A 라는 메소드가 있고, A 메소드는 A 메소드의 결과를 기반으로 B 메소드를 호출하고, B 메소드는 B 메소드의 결과를 기반으로 C 메소드를 호출하도록 구현되어 있을 때를 가정. 만약 A 메소드의 동작이 일부 수정해야한 다면 B,C 메소드를 전부 바꿔야하는 상황이 발생함. 이 때 유지보수가 매우 비효율적인 것을 알 수 있기 때문에 모두 분리해줄 필요가 있음.
2) 개방 폐쇄 원칙 OCP
: 소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다.
- 기존의 코드를 변경하지 않고 기능을 수정하거나 추가할 수 있도록 설계해야 함
- 지키지 않을 시, 다운 캐스팅이 발생
- 다운 캐스팅 : 자식 클래스의 객체가 부모 클래스 타입으로 형변환 되는 것을 다시 원상태로 돌리는 것
- 자주 변하는 부분을 추상화함으로서 기존 코드를 수정하지 않거도 기능을 확장할 수 있도록 함
- 유연함을 높이는 것이 핵심
3) 리스코프 치환 원칙 LSP
: 프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 서브타입(하위 클래스)은 어디서나 자신의 기반타입(상위 클래스) 인스턴스로 바꿀 수 있어야 한다.
- 하위 클래스 객체는 상위 클래스 객체에서 가능한 행위를 수행할 수 있어야 함
- = 상위 클래스 객체를 하위 클래스 객체로 치환해도 정상적으로 동작해야 함
- LSP를 지키지 않을 시 OCP도 위반하게 되는 것
- 기능 확장을 위해 기존의 코드를 여러 번 수정해야 하기 때문
4) 인터페이스 분리 원칙 ISP
: 클라이언트는 자신이 사용하는 메소드에만 의존해야 한다.
- 한 클래스는 자신이 사용하지 않는 인터페이스는 구현하지 않아야 함
- 여러 개의 세부적인 인터페이스가 낫다는 것
- 각 클라이언트가 필요로 하는 인터페이스를 분리함으로서, 클라이언트가 사용하지 않는 인터페이스에 변경이 변경이 발생하더라도 영향을 받지 않도록 함
5) 의존관계 역전 원칙 DIP
: 구체화에 의존하기 보단 추상화에 의존해야 한다.
- 추상화 : 변하기 어려운
- 구체화 : 변하기 쉬운
- 고차원의 모듈은 저차원의 모듈에 의존하면 안됨
- 저차원의 모듈이 변경되어도 고차원의 모듈은 변경이 필요없는 형태가 이상적
- 자신보다 변하기 쉬운 모듈에 의존하면 안된다는 뜻
정리
- 단일 책임 원칙과 인터페이스 분리 원칙은 객체가 커지는 것을 막아줌
- 객체가 단일 책임을 갖도록 하고 클라이언트마다 세부적인 인터페이스를 구현하게 해서
- 한 기능의 변경이 다른 곳까지 미치는 영향을 최소화 시킴
- 기능 추가/변경에 용이하도록 만들어 줌
- 리스코프 치환 원칙과 의존관계 역전 원칙은 개방 폐쇄 원칙을 서포트 해줌
- 개방 폐쇄 원칙은 자주 변화되는 부분을 추상화하고 다형성을 이용하여 기능 확장에는 용이하게, 기존 코드의 변화에는 보수적이게 만듬
- 변화되는 부분 추상화 = 의존관계 역전 원칙
- 다형성을 이용 = 리스코프 치환 원칙