객체지향 설계의 5가지 원칙
SOLID 원칙?
객체지향 설계를 할 때, SOLID 원칙을 지켜줘야 한다는 얘기는 정보처리기사 공부를 했다면 한번쯤은 들어봤을 것이다. (그리고 자격증을 취득하면 귀신같이 잊어버린다.)
SOLID 용어는 다음과 같이
- 단일 책임 원칙(Single Responsibility)
- 개방-폐쇄 원칙(Open Closed Principle)
- 리스코프 치환 원칙(Liskov Substitutuib Principle)
- 인터페이스 분리 원칙(Interface Segregation Principle)
- 의존 역전 원칙(Dependency Inversion Principle)
다섯가지 원칙의 앞 글자를 따서 만든 용어다. 그렇다면 이제부터 이 5가지 원칙에 대해 하나하나 자세히 파고들어 보도록 하겠다.
1. 단일 책임 원칙
하나의 클래스는 단 하나의 책임만 가져야 한다 (=하나의 클래스를 변경할 이유는 단 하나뿐이어야 한다)
여기서 책임이란 '기능' 정도의 의미라고 생각하면 된다. 즉, 하나의 클래스는 하나의 기능만 가지고 있어야 한다는 이야기다. 만약 하나의 클래스에 책임이 여러 개 존재하면 클래스 내부의 함수끼리 결합이 강해질 수 있다. 함수 간의 결합이 강해지면 유지보수에 불리해지기 때문에 반드시 책임을 잘게 쪼개어 분리해야 한다.
2. 개방-폐쇄 원칙
소프트웨어 요소는 확장에는 개방적이고, 변경에는 폐쇄적이어야 한다
소프트웨어란 개발하면서 항상 확장된다. 포인트는 이 확장을 하는 도중, 다른 요소가 변경되는 일은 없거나 최소화돼야 한다는 점이다. 예를 들어 새로운 요소가 추가될 때마다 기존의 코드를 갈아엎는 일이 발생한다면, 그 코드는 개방-폐쇄 원칙을 지키지 않은 코드라는 의미가 된다. 개방-폐쇄 원칙을 지키기 위해서는 반드시 추상화에 의존해야 한다.
3. 리스코프 치환 원칙
객체는 프로그램의 정확성을 깨지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다
하위 타입은 항상 상위 타입을 대체할 수 있어야 한다는 원칙이다. 객체 지향 언어에서 자식 객체는 부모 객체를 상속 받아 만들어지는데, 이때 부모 객체는 상위 타입이 되고 자식 객체는 하위 타입이 된다. 즉, 부모 객체를 이용해 구현한 코드는 자식 객체로 변경하더라도 문제없이 코드가 실행되어야 한다.
4. 인터페이스 분리 원칙
클라이언트는 자신이 사용하는 함수에만 의존해야 한다
이 원칙은 달리 말하자면, 클라이언트는 자신이 사용하지 않는 함수를 의존하지 말아야 한다는 의미기도 하다. 자신이 사용하지 않는 함수에 의존하지 않으려면 범용적인 인터페이스 하나 보다는 여러 개의 구체적인 인터페이스로 분리하여 제공하는 것이 좋다.
5. 의존 역전 원칙
의존 관계를 맺을 때, 변화하기 쉬운 것(구체화) 보다는 변화하기 어려운 것(추상화)에 의존해야 한다
변화하기 쉬운 것은 구체 클래스고 변화하기 어려운 것은 인터페이스다. 즉, 위에서 길고 어렵게 적어 놨지만 핵심만 얘기하면 클래스를 구현할 때는 구체 클래스에 의존하지 않고 인터페이스에 의존해야 한다는 의미다. 인터페이스에 의존하게 되면 인터페이스로 추상화 한 대상인 구체 클래스에 변경사항이 있더라도 인터페이스에 의존하는 클래스는 코드를 변경하지 않아도 된다. 의존 역전 원칙은 개방-폐쇄 원칙과도 밀접한 관련이 있다. 의존 역전 원칙이 위배되면, 개방-폐쇄 원칙도 위배되었을 가능성이 높다.
정리하며
면접도 준비 할 겸, 컴퓨터 과학 지식 중에서 자주 나올 법한 내용에 대해 하나하나 정리해 나가는 중이다. 시간이 난다면 5개의 원칙을 코드를 통해 자세한 설명을 하려고 한다.