SOLID 원칙은 지속 가능하고 유지 보수가 용이한 시스템을 설계하는 데 있어 핵심적인 지침으로 현재 소프트웨어 분야에서 사용되고 있다.
SOLID는 5가지 객체 지향 설계 원칙의 첫 글자를 따서 만든 약어로, 각각은 다음과 같다.
단일 책임의 원칙이란, 하나의 객체는 반드시 하나의 기능만을 수행하는 책임을 갖는다는 원칙이다.
객체가 담당하는 동작, 즉 책임이 많아질수록 그 객체의 변경에 따른 영향도의 양과 범위가 커진다.
SRP를 통해 책임영역이 확실하게 되어 한 책임의 변경에서 다른 책임의 변경의 연쇄작용에서 자유로워진다.
즉, 단일 책임 원칙은 특정 객체의 책임 의존성 과중을 지양하기 위한 중요하고 기본적인 원칙이다.
개방 폐쇄 원칙이란, 객체의 확장은 개방적으로, 객체의 수정은 폐쇄적으로 대해야 한다는 원칙이다.
기능은 변하거나 확장되는 것은 가능하지만, 그 과정에서 기존의 코드가 수정되지 않아야 한다.
대표적으로 프로그래밍시 사용하는 라이브러리의 경우, 라이브러리를 사용하는 객체의 코드가 변경된다고 해서 라이브러리의 코드까지 변경하지는 않는다.
이렇게 어떤 하나의 객체를 수정해야 하는 상황에서, 해당 객체에 의존하는 다른 객체들까지 줄줄이 수정해야 한다면 좋은 설계라고 보기 힘들다.
OCP를 통해서 객체간 의존성을 최소화하여 코드 변경에 따른 영향력을 낮출 수 있다.
리스코프 치환 원칙이란, 부모 객체와 자식 객체가 있을 때 부모 객체를 호출하는 동작에서 자식 객체가 부모 객체를 완전히 대체할 수 있다는 원칙이다.
객체 지향 프로그래밍에서 상속이 발생하면 하위 타입인 자식 객체는 상위 타입인 부모 객체의 특성을 가지며, 그 특성을 토대로 확장할 수 있다.
간단히 말하자면, 리스코프 치환 원칙은 올바른 상속을 위해, 자식 객체의 확장이 부모 객체의 방향을 온전히 따르도록 권고하는 원칙이다.
인터페이스 분리 원칙이란, 객체란 자신이 사용하는 메서드에만 의존해야 한다는 원칙이다.
이 말은 객체가 사용하지 않는 메서드를 의존해서는 안된다는 의미이다.
인터페이스는 지나치게 광범위하거나 지나치게 많은 기능을 구현해서는 안된다.
오히려 그 인터페이스를 사용하는 객체를 기준으로 작게 분리되어야 한다.
예를 들어 interfaceA의 메서드 op1, op2, op3가 있고, 이 인터페이스를 User1, User2, User3 객체들이 상속을 받았다는 가정을 했다.
이중 User1은 오직 op1만을, User2은 오직 op2만을, User3은 오직 op3만을 사용한다 했을 때, User1은 op2를 사용하지 않음에도 불구하고 만약 op2 메서드에 변경이 일어나면, 함께 변경되어 재 컴파일 & 재 배포 과정을 거쳐야 하는 문제가 발생한다.
이러한 경우에 ISP를 이용하여 인터페이스를 잘게 분리한다면 각각의 객체들은 오직 자신이 필요한 메서드만을 사용할 수 있는 구조가 된다.
의존성 역전 원칙이란, 추상화에 의존하고, 구체화에 의존하면 안 된다는 원칙이다.
즉, 고수준 모듈은 저수준 모듈의 구현에 의존해서는 안 되며, 대신 저수준 모듈이 고수준 모듈에서 정의한 추상 타입에 의존해야 한다는 의미이다.
여기서 말하는 고수준 모듈은 Interface, 추상 클래스를 의미하고, 저수준 모듈은 메인 클래스나 객체를 의미한다.
사실 고수준 클래스가 저수준 클래스를 사용하므로 고수준 클래스가 저수준 클래스에 의존하는 것이 자연스러워 보인다.
하지만 저수준 클래스는 빈번하게 변경되고, 새로운 것이 추가될 때마다 고수준 클래스가 영향을 받기 쉽기 때문에 의존관계를 역전시켜야 한다.