[Java] 모듈 결합도와 응집도
오늘은 모듈 결합도와 응집도 개념과 객체 지향 프로그래밍의 5가지 원칙인 SOLID에 간략하게 알아보겠습니다.
SOLID 원칙
우리가 SOLID를 알아야 하는 이유
먼저, SOLID은 객체 지향 프로그래밍 원칙입니다. 설계 원칙을 모른다고 자바 프로그래밍을 할 수 없는 것은 아닙니다. 충분히 자바 프로그래머로서 일을 할 수 있습니다. 그럼에도 우리가 이를 학습해야 하는 이유는 무엇일까요?
결론부터 말씀 드리면, SOLID 원칙은 객체 지향 프로그랭을 할 때 발생될 수 있는 문제들을 해결하기 위한 검증된 프로그래밍 방법론이기 때문입니다. 비록 이러한 문제들을 직접 마주한 경험이 없더라도, SOLID 원칙을 학습하면서 개발하며 발생할 수 있는 문제에 대해 미리 알게 되고 그에 대한 해결책까지 알 수 있습니다. 덤으로 더 깔끔하고 좋은 코드를 작성하는 방법을 자연스럽게 알게 됩니다. 따라서 이를 학습하는 것은 우리들에게 꽤 유용합니다.
또한 소통에 있어서의 부가적인 효과도 거둘 수 있습니다.
- 효율적인 의사소통 방법을 위한 공통 언어 제공
동료의 코드를 리뷰하는 상황을 가정해봅시다. 코드 리뷰 시, "이 클래스는 OCP 원칙에 부합되지 않습니다"라고 말할 수 있고 (SOLID 원칙을 아는 개발자라면) 어떤 부분에 문제가 존재하는지 쉽게 파악할 수 있도록 아이디어를 제공할 수 있습니다.
결합도와 응집도
결합도와 응집도는 모듈(클래스도 포함됩니다)의 독립성을 판단하는 대표적인 지표입니다. 이는 SOLID 원칙과도 연관됩니다. 결합도란 모듈과 모듈 간 의존 정도를 말하며, 응집도란 모듈 내부의 기능적인 집중 정도를 말합니다. 결합도는 낮으면 낮을수록, 응집도는 높으면 높을수록 이상적입니다. SOLID 원칙을 준수하면 클래스 간 결합도는 낮아지고 응집도는 높아집니다.
결합도가 높은 코드의 문제
클래스 간 결합도가 높으면 어떤 문제가 발생할 수 있을까요?
- 회귀 테스트에 대한 필요성 증가
Car 클래스를 수정해야 하는 상황이라고 가정합시다. Car 클래스와 Bicycle 클래스 간 결합도가 높다고 가정할 때, Car 클래스를 수정하려면 연관된 Bicycle 클래스의 코드도 수정해야 하는 상황이 생깁니다. 문제를 해결하기 위해서, 넓은 범위의 코드를 수정해야 합니다. 연관된 클래스의 역할을 이해해야며, 문제해결에 더 오랜 시간이 소요됩니다. 또 수정 시, 회귀 테스트를 진행해야 합니다. 회귀 테스트란 이미 정상 동작이 확인된 프로그램의 테스팅을 반복하는 것을 말합니다. 이는 결함 수정 이후 변경된 코드로 인해 새로운 문제가 발생할 수 있기 때문입니다. 테스트코드가 작성되어 있다면, 회귀 테스트를 쉽게 수행할 수 있겠지만, 그렇지 않다면 수동 테스트를 진행해야 합니다.
- 코드 재사용성 감소
클래스 재사용이 어려워집니다. 보통 결합도가 높으면, 기능적 독립성이 낮습니다. 독립성이 낮으면 기능을 분리해서 사용하기 어려워집니다. 분리하기 어렵기 때문에 코드 재사용이 어려워집니다. 전부 그런 것은 아니지만, 일반적으로 코드 재사용율이 낮으면 추가적으로 개발 시간이 소요되므로 비효율적인 상황이 발생할 수 있습니다.
- 유지보수 하기 어려운 코드
반대로 결합도가 낮은 코드는 위 문제들이 해결된 코드입니다. 후술할 SOLID 원칙 중 OCP 원칙과 연관이 깊으며, 아래의 특성을 가집니다.
- 확장에는 개방되고, 변경에는 폐쇄적인 클래스 (OCP의 원칙을 가진 클래스)
- 다형성이 좋은 클래스
- 유지보수 하기 쉬운 코드
응집도가 낮은 코드의 문제
앞서 응집도란 모듈 내부의 기능적인 집중 정도라고 이야기했습니다. 결합도와 반대로, 응집도는 낮을수록 문제입니다. 응집도에 속하는 대표적인 예시가 기능적 응집도입니다. 기능적 응집도란 모듈 내부의 모든 기능이 단일 목적을 위해 수행되는 경우를 말합니다. 그렇다면 클래스 간 응집도가 낮으면 어떤 문제가 발생할 수 있을까요?
- 코드 재사용성 감소
응집도가 낮은 클래스는 연관이 적은 여러 기능들을 수행합니다. 이는 자연스레 결합도 역시, 높아지게 됩니다. 이에 따라 재사용성은 낮아지고 유지보수는 어려워집니다.
- 코드 가독성 감소
연관이 적은 기능들이 함께 존재하기 때문에, 어떤 역할을 수행하는 클래스인지 파악하기 어려워집니다. 이로 인해 코드 가독성이 감소하게 되며, 다른 개발자가 한 눈에 기능을 파악이 어려워지게 됩니다.
- 유지보수가 어려운 코드
한 클래스에서 여러 기능을 담당하기 때문에, 유지보수가 어렵습니다. 하나의 기능을 수정하면 다른 코드에 영향을 줄 수 있기 때문입니다.
반대로 응집도가 높은 클래스는 어떠한 특성을 가질까요? 아래와 같은 특성을 갖습니다.
- 단일 책임을 가진 클래스 (SRP 원칙을 준수하는 클래스)
- 다른 클래스와 잘 협력할 수 있는 클래스
- 유지보수하기 쉬운 코드
아래의 문제점들을 개선되어, 장점이 됩니다.
다음 시간에는 본격적으로 SOLID 원칙에 관해 알아보도록 하겠습니다.
참고한 사이트
https://refactoring.guru/design-patterns/why-learn-patterns
https://dev-coco.tistory.com/64