[JAVA] SOLID, 좋은 코드를 위한 5가지 원칙
SOLID, 좋은 코드를 위한 5가지 원칙
글쓰기에 앞서, 해당 글은 김영한님의 스프링 핵심 원리 - 기본편을 참고하여 적었습니다. 수업에서 제가 이해한 대로 적었기 때문에 좋은 마음으로 봐주시고 지적점이 있으면 소중한 댓글 한번 부탁드립니다.
SOLID란?
SOLID란 5가지 원칙 각각의 맨 첫 알파벳을 따온 것으로
S - SRP: Single Responsibility Principle (단일 책임의 원칙)
O - OCP : Open Close Principle(개방-폐쇄의 원칙)
L - LSP : Liskov Substitution Principle(리스코프 치환의 원칙)
I - ISP : Interface Sergregation Principle(인터페이스 분리의 원칙)
D - DIP : Dependency Inversion Principle(의존 관계 역전의 원칙)
총 5가지로 구성되어있습니다.
1. SRP: Single Responsibility Principle (단일 책임의 원칙)
단일 책임의 원칙이란, 하나의 클래스는 하나의 책임만을 가져야한다는 원칙입니다. 예를 들자면 제 자신을 My라 칭하는 클래라 하면 저는 개발자 일때는 개발하기와 디버깅하기 등의 역할,즉 책임이 있고, 가족에서는 막내로서 분리수거하기, 집안일 돕기등의 역할을 가진 구현체, 친구들에게는 같이 놀기, 밥먹기라는 역할을 하는 구현체 총 세개를 가져야한다고 했을때,
My라는 클래스는 3개의 책임을 가지게 됩니다. 이것은 SRP에 위반되기 때문에, 인터페이스를 My개발자, My막내,My친구처럼 3개로 나누어서 하나의 클래스가 하나의 책임을 가지게 해야하는 것이 맞다고 생각합니다.
또한 강의에서는 무언가(Ex:UI)를 변경할 때, 타격이 적을 수록 SRP를 잘 지켰다고 생각하신다 들었습니다. 저도 동의하는 것이 당연히 단일 책임의 원칙을 잘 지켰다면, 기능변경에 따른 변경점은 SRP를 안지켰을 때보다 훨씬 적어진다고 생각합니다. 안 지켜졌다면 나머지 3개의 책임에 대한 구현체의 코드를 모두 변경해야하니까요.
2. OCP : Open Close Principle(개방-폐쇄의 원칙)
OCP는 개방-폐쇄의 원칙을 나타냅니다. 무슨 뜻이냐고 깊게 들어가면 기능의 확장에는 열려있으나(구현체) 기능의 변경에는 닫혀있어야(인터페이스)한다고 합니다.
인터페이스에는 구현해야할 기능의 핵심이 담겨있습니다. 예를 들어 볼펜이라는 인터페이스에 색을 구현하는 메서드가 정의되어있으면, A구현체는 색깔을 빨간색으로 구현하고, B구현체는 색깔을 파란색으로 구현하면 이것이 기능의 확장입니다. 또한 기존 Controller에서는 인터페이스에 대한 코드를 전혀 변경할 필요가없습니다. Spring에서는 Component지정을 바꾸거나 @Service 어노테이션만 바꿔달면 됩니다. 하지만 색을 정하는 메서드만 가진 볼펜 인터페이스에 on/off기능을 추가하는 것은 ocp를 위반한다는 것이죠. 이것이 기능을 변경하는 일이 되는 겁니다. 이렇듯 개방 폐쇄의 원칙역시도 신경써야한다는 겁니다.
3. LSP : Liskov Substitution Principle(리스코프 치환의 원칙)
LSP는 리스코프 치환의 원칙으로, 상위 객체와 하위 객체를 바꿔도 정상적으로 작동해야하는 원칙을 의미합니다.
자동차에 빗대어 만약 엑셀을 밟을 때 속도가 증가해야하는 목적이지만, 하위객체에서 속도를 감소하게 한다면 정상 작동은 되겠지만 의도를 벗어나는 객체가 되어버립니다. 이런 경우는 리스코프 치환의 원칙을 위반했다 할 수 있습니다.
4. ISP : Interface Sergregation Principle(인터페이스 분리의 원칙)
ISP는 인터페이스 분리의 원칙으로, 위의 SRP(단일 책임의 원칙)과 내용이 비슷합니다. 범용 인터페이스로 모든 것을 구현하는 것보다, 특정 기능들에 맞춰 여러개의 인터페이스로 구성해야한다는 것이죠, 만약 하나의 인터페이스에 키보드의 기능, 마우스의 기능을 모두 넣어놓으면 구현체에서 전부 다 구현을 하긴 해야하기때문에, 각각의 인터페이스로 분리하는 것이 ISP를 잘 지키고 있다고 할 수 있습니다.
5. DIP : Dependency Inversion Principle(의존 관계 역전의 원칙)
의존 관계는 사실 인터페이스를 부르면 구현체를 불러와 해당 구현체에 대한 코드가 실행되지만, 구현 클래스에 의존하지 말고 인터페이스(역할)에 의존하라는 원칙입니다. 만약 구현체에 의존하게 되면 이후 유지보수나 업데이트시 기능변경이 매우 어려워집니다.(개발의 중점이 구현체에 있으면 인터페이스의 변경이 어려워 질 수 있기 때문인것 같습니다.)
이상으로 SOLID에 대한 설명이 모두 끝났는데요, 글을 작성하면서 나는 여태까지 어떻게 설계했었는지를 되돌아보게 되었음과 동시에 적었는데도 개념이 잘 안잡히는 부분들이 있는것 같습니다. 앞으로도 여러번 상기해봐야할 SOLID원칙입니다. 끝까지 봐주셔서 감사합니다!