첫 실무에서 가장 많이 와 닿았던, 그리고 내가 학부 시절 많이 부족했던 지식 중 하나였다.
객체지향 5대 원칙이라고 부르는 SOLID, 한번 깊게 파 보자.
객체지향 프로그램을 설계 할 때 중요하게 여기는 것들이 여러가지 있다.
결국 시간이 오래 지나도 유지보수하기 쉽고 확장이 쉬운 프로그램이 오랫동안 서비스 될 수 있다. 시장에서 오래 서비스되는 프로그램을 개발하는 팀의 팀원들은 오랜 기간이 지났을 만큼 많은 교체가 있을 수 있다. 즉 한번 누가 짜 놓은 코드를 누군가 다른 사람이 읽고 보수를 해야 할 수 있다는 것.
유지보수라는 개념을 학부 때 와닫기는 상당히 어렵다. 사실 유지 보수 그 자체는 본인이 할 일이 아닐 수 있다. 학부 때 프로젝트의 특징이 뭐였는가? 일단 돌아가면 제출하고 땡이었다. (제가 그렇단 말입니다...)
하지만 서비스는 오랜 시간 지속 되어야 하고 변동 사항이 생길 수 있다. 퇴사자가 생기면 퇴사자 대신해서 누군가가 그 코드를 봐야한다. 아니 꼭 퇴사가 아니더라도 담당 모듈이 바뀌거나 팀이 바뀔 수도 있다. 아무도 모른다.
즉 많은 개발자들이 해당 코드를 보고 이해하기 쉽고 리펙토링 하기 쉬우며 코드의 나쁜 냄새들을 제거할 수 있도록 이러한 원칙이 생겨 난 것이다.
SRP. 단일 책임의 원칙이다.
한 클래스는 하나의 책임만을 져야 한다. 그리고 클래스는 자신의 책임을 완전히 캡슐화 해야 한다.
만약 한 클래스가 여러가지 기능을 가지고 여러가지 책임을 가지게 된다면 클래스를 구성하는 코드 그 자체가 꼬일 수도 있다.
그리고 그 객체를 사용하는 비즈니스 로직에 문제가 생길 수도 있다. 그러므로 클래스 그 자체의 책임을 벗어나지 않도록 역할을 명확히 해야 한다.
OCP. 개방 폐쇄 원칙이다.
소프트웨어의 요소는 확장에는 열려 있으나, 변경에는 닫혀 있어야 한다는 것이다.
확장에 대해 닫혀있다는 것은, 말 그대로 요구사항에 대한 확장이 가능하다는 것이고 변경에 대해 닫혀있다는 것은, 모듈의 소스코드나 바이너리 코드를 수정하지 않아도 모듈의 기능을 확장 하거나 변경 할 수 있다는 의미다.
이런 원칙 때문에 추상화라는 개념을 사용한다. 객체 지향에서 abstract class 등을 활용했을 때 그 클래스를 확장시켜서 또 다른 클래스를 생성 시키는 건 쉽지만, 그 클래스 자체가 가지고 있는 절대로 변할 수 없는 값들을 변경 시킬 수 없다. 그러므로 추상화 기능을 사용한다면 OCP를 잘 따르는 클래스를 설계 할 수 있다.
LSP. 리스코프 치환 원칙이다.
프로그램의 객체는 프로그램의 정확성을 깨트리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다는 원칙이다.
만약 데이터타입 S가 데이터타입 T의 하위형이라면 필요한 프로그램의 속성의 변경 없이 데이터타입 T의 객체를 데이터타입 S의 객체로 교체할 수 있어야 한다는 원칙이다.
조금 쉽게 얘기하면 부모 객체를 호출하는 동작에서 자식 객체가 부모 객체를 대체할 수 있다는 것이다.
이 원칙이 존재 함으로써 객체지향 언어에서 상속이 일어날 때 객체의 어긋난 확장으로 일어남으로써 생기는 문제를 막아준다. 오직 자식 객체의 확장은 부모 객체의 방향을 따르어야 한다.
이 원칙을 준수하기 위해서는 상속관계를 명확히 해야하고 클래스를 설계 할 때 상속의 방향이 부모에서 자식으로 올바르게 흘러가는 지 확인 하는 과정을 거쳐야 한다.
ISP. 인터페이스 분리 원칙이다.
특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다는 원칙이다.
클라이언트가 자신이 이용하지 않는 메서드에 의존하지 않아야 한다는 원칙이다. 큰 덩어리의 인터페이스들을 작은 단위로 나누어서 꼭 필요한 메서드만 이용할 수 있도록 도와주는 원칙이다.
DIP. 의존관계 역전 원칙이다.
상위 모듈은 하위 모듈에 의존 해서는 안 되고, 추상화는 세부 사항에 의존 해서는 안된다. 즉, 이미 구현 되어있는 객체가 아니라 인터페이스와 같은 객체의 형태나 추상적 개념에 의존해야 한다는 것이다.
객체는 객체보다 인터페이스에 의존해야지 객체간에 의존도가 높아지면 여러모로 프로그램 객체 간에 의존도가 높아지므로 에러가 생겼을 때 수정하기 매우 힘들어진다.
SOLID 법칙에 대해 이해하고 있다는 것은, 마냥 클래스에서 객체를 만들어서 활용하는 수준을 넘어 훨씬 안정적인 객체지향 코드를 개발 해 낼수 있는 밑거름이 된다.
다음 포스팅은 소프트웨어 개발 3대 원칙이라 불리는 KISS, YAGNI, DRY에 대해 써 보도록 하겠다.