
코드의 디커플링
소프트웨어 설계와 개발 과정에서 코드의 복잡성
은 가독성
과 유지보수성
과 연관이 있기 때문에 우리는 코드의 복잡성
을 제어해야한다.
그리고 코드의 복잡성을 제어하는 가장 효과적인 방법은 디커플링
이다.
디커플링
을 통해응집도
가 높고결합도
가 낮은 코드를 만들 수 있다.
높은 응집도와 낮은 결합도
높은 응집도
와 낮은 결합도
는 클래스 간의 세분화된 관계 설계를 이끌어 낼 뿐만아니라 세분화된 시스템, 아키텍처, 모듈의 설계를 이끌어내는 일반적인 사상이다.
- 코딩 규칙에 비하여 더 높은 수준에서 코드의
가독성
과유지보수성
을 향상 시킬 수 있다. - 높은
응집도
와 낮은결합도
의 특성을 활용한다면, 다른 모듈이나 클래스 코드에 대해 너무 많이 이해할 필요 없이 모듈이나 클래스에 집중할 수 있다. 의존성
이 간단하고결합도
가 낮아 코드 수정이 전체적인 코드에 영향을 미치지 않으며, 버그의 발생 가능성을 줄여준다.- 코드의 전체 구조를 조정하는 작업 없이도 특정 모듈이나 클래스에 집중하는 소규모 리팩터링이 가능하며, 리팩터링 난이도가 대폭 하락할 수 있다.
- 높은
응집도
와 낮은결합도
를 가진 코드는 그 구조가 명확하고계층화
와모듈화
가 합리적이며의존성
이 간단하고 모듈이나 클래스 사이의결합도
가 낮다는 것을 의미한다.
언제 코드를 디커플링 해야하는가?
그렇다면 언제 코드를 디커플링
해야할까? 그 기준은 다양하겠지만, 다음과 같은 상황에서는 디커플링
을 우선적으로 고려해보는 것이 좋다.
- 기능의 코드의 일부가 수정되면 전체 코드를 모두 건드려야 하는 상황이 발생할 경우(프로젝트 코드 결합도가 너무 높아 디커플링이 필요하다.)
- 모듈과 클래스 사이의 의존 관계가 복잡하고 혼잡한 경우(코드 구조의 문제)
코드를 디커플링 하는 방법
1. 캡슐화와 추상화를 활용한다.
캡슐화
와 추상화
는 시스템
, 모듈
, 클래스 라이브러리
, 구성 요소
, 인터페이스
,클래스 설계
와 같은 다양한 코드 설계 시나리오에 적용이 가능하다.
캡슐화
와추상화
는 구현의복잡성
을 효과적으로 숨길 수 있다.- 구현의 변동성을 격리하며,
상위 모듈
(호출자)에게 안정적이고 사용하기 쉬운인터페이스
를 제공할 수 있다.
2. 중간 계층을 사용한다.
중간계층
은 모듈 사이 또는 클래스 사이의 의존성
을 단순화 할 수 있다.
중간계층
의 도입은 모듈간의 의존성을 단순화하고 코드 구조를 더 명확하게 만들 수 있다.리팩터링
을 진행할 때도중간계층
이 과도기적 역할을 할 수있어 개발 프로세스와리팩터링
프로세스가 서로 간섭하지 않고 동시에 진행 될 수 있다.- 단계적으로 리팩터링이 가능하다.
- 리팩터링 프로세스와 개발 프로세스가 서로 충돌할 가능성이 낮아진다.
3. 모듈화와 계층화를 적용한다.
복잡한 시스템을 개발하고 유지할 수 있는 주된 이유는 전체 시스템을 프로세스 스케줄링
, 프로세스 통신
, 메모리 관리
, 가상 파일 시스템
, 네트워크 인터페이스 모듈
등 여러 개의 독립적인 모듈
로 분할하기 때문이다.
모듈화
는 복잡한 시스템을 구축할 때 사용되는 일반적인 수단이다.모듈
은인터페이스
를 통해 통신하며모듈
간의결합도
는 매우 낮다.모듈
은 독립적인클래스 라이브러리
로 개발해야 한다.모듈
은 다른 모듈이 클래스의 내부에 접근할 수 있도록 구현 세부사항을캡슐화
하여,인터페이스
형식으로 제공해야 한다.
모듈화
의 개념은서비스 기반의 아키텍처(SOA)
,마이크로 서비스(MSA)
,클래스 라이브러리
,클래스
와 기능의 설계에 반영된다.
모듈화의 본질은 분할을 통한 제어 이다.
모듈화
외에도 계층화
는 복잡한 시스템을 구축하는 일반적인 수단이며, 복잡한 시스템이 발전할수록 계층화 기술을 최대한 이용해야 한다.
- 각 계층은 구현 세부 사항을
캡슐화
하고 상위 계층에서 사용할추상 인터페이스
를 노출한다. - 다른 계층의 코드에 영향을 주지 않고 각 계층을 다시 구현하거나 업데이트 할 수 있다.
재사용
이 용이하고 특정 비즈니스와 관계 없는 코드는 최대한 하위계층으로 내리고, 수정이 빈번한 특정 비즈니스와 깊게 관련된 코드는 상위 계층으로 올려야한다.
4. 단일 책임 원칙을 준수한다.
단일 책임 원칙
은 높은 응집도
를 달성하기 위한 가장 중요한 지침이다.
- 모듈이나 클래스에 단일 책임이 있는 경우 해당 클래스에 의존하는 클래스와 해당 클래스가 의존하는 클래스의 수가 줄어들고 코드의
결합도
가 낮아진다. 응집도
와결합도
는 서로 독립적인 요소가 아니기 때문에 응집도가 높으면 코드의 결합도가 낮아지게 된다.
5. 구현이 아닌 인터페이스 기반의 프로그래밍을 한다.
인터페이스 기반의 프로그래밍
은 의존성이 있는 두 개의 모듈 또는 클래스 사이에서 어떤 모듈이나 클래스의 변경사항이 다른 모듈 또는 클래스에 영향을 미치지 않는다.
6. 의존성 주입을 활용한다.
의존성 주입
은 모듈 또는 클래스 사이의 강한 결합을 약한 결합으로 바꿀 수 있다.
의존성 주입
이 원래 의존성이 있어야 하는 두 개의 클래스를 의존성이 없는 형태로 바꿀 수 있는 것은 아니다.- 최소한 두 클래스 사이의 결합정도를 원래보다 낮출 수 있으며, 의존하고 있는 클래스를 다른 클래스로 쉽게 바꿀 수도 있다.
7. 상속보다는 합성을 더 많이 사용한다.
상속
은 강한 의존 관계에 해당하여 상위 클래스의 변경은 모든 하위 클래스에 영향을 미친다. 하지만 합성
은 약한 의존관계로 복잡한 상속관계를 합성으로 대체하면 디커플링이 가능해진다.
상속
은인터페이스
,합성
,위임
을 통해 완전히 대체 가능하다.
8. LoD 를 준수한다.
LoD
를 사용하는 목적은 코드의 결합도
를 낮게 유지하기 위해 사용한다.
LoD
에서는 직접 의존성이 없어야 하는 클래스 사이에는 반드시 의존성이 없어야 하며, 의존성이 있는 클래스는 필요한인터페이스
에만 의존해야한다.
'개인공부 > 아키텍처' 카테고리의 다른 글
[ 아키텍처 ] 파이프-필터 아키텍처 (1) | 2023.11.03 |
---|---|
[ 아키텍처 ] 로드밸런싱 패턴 (1) | 2023.10.29 |
[ 아키텍처 ] 클린아키텍처에서의 유스케이스 구현하기 (0) | 2023.08.02 |
[ 아키텍처 ] 클린아키텍처의 구성과 패키지 구조 (0) | 2023.07.24 |
[아키텍처] 클린아키텍처(Ports and Adapters): 왜 클린 아키텍처를 공부하게 되었는가? (0) | 2023.07.20 |

코드의 디커플링
소프트웨어 설계와 개발 과정에서 코드의 복잡성
은 가독성
과 유지보수성
과 연관이 있기 때문에 우리는 코드의 복잡성
을 제어해야한다.
그리고 코드의 복잡성을 제어하는 가장 효과적인 방법은 디커플링
이다.
디커플링
을 통해응집도
가 높고결합도
가 낮은 코드를 만들 수 있다.
높은 응집도와 낮은 결합도
높은 응집도
와 낮은 결합도
는 클래스 간의 세분화된 관계 설계를 이끌어 낼 뿐만아니라 세분화된 시스템, 아키텍처, 모듈의 설계를 이끌어내는 일반적인 사상이다.
- 코딩 규칙에 비하여 더 높은 수준에서 코드의
가독성
과유지보수성
을 향상 시킬 수 있다. - 높은
응집도
와 낮은결합도
의 특성을 활용한다면, 다른 모듈이나 클래스 코드에 대해 너무 많이 이해할 필요 없이 모듈이나 클래스에 집중할 수 있다. 의존성
이 간단하고결합도
가 낮아 코드 수정이 전체적인 코드에 영향을 미치지 않으며, 버그의 발생 가능성을 줄여준다.- 코드의 전체 구조를 조정하는 작업 없이도 특정 모듈이나 클래스에 집중하는 소규모 리팩터링이 가능하며, 리팩터링 난이도가 대폭 하락할 수 있다.
- 높은
응집도
와 낮은결합도
를 가진 코드는 그 구조가 명확하고계층화
와모듈화
가 합리적이며의존성
이 간단하고 모듈이나 클래스 사이의결합도
가 낮다는 것을 의미한다.
언제 코드를 디커플링 해야하는가?
그렇다면 언제 코드를 디커플링
해야할까? 그 기준은 다양하겠지만, 다음과 같은 상황에서는 디커플링
을 우선적으로 고려해보는 것이 좋다.
- 기능의 코드의 일부가 수정되면 전체 코드를 모두 건드려야 하는 상황이 발생할 경우(프로젝트 코드 결합도가 너무 높아 디커플링이 필요하다.)
- 모듈과 클래스 사이의 의존 관계가 복잡하고 혼잡한 경우(코드 구조의 문제)
코드를 디커플링 하는 방법
1. 캡슐화와 추상화를 활용한다.
캡슐화
와 추상화
는 시스템
, 모듈
, 클래스 라이브러리
, 구성 요소
, 인터페이스
,클래스 설계
와 같은 다양한 코드 설계 시나리오에 적용이 가능하다.
캡슐화
와추상화
는 구현의복잡성
을 효과적으로 숨길 수 있다.- 구현의 변동성을 격리하며,
상위 모듈
(호출자)에게 안정적이고 사용하기 쉬운인터페이스
를 제공할 수 있다.
2. 중간 계층을 사용한다.
중간계층
은 모듈 사이 또는 클래스 사이의 의존성
을 단순화 할 수 있다.
중간계층
의 도입은 모듈간의 의존성을 단순화하고 코드 구조를 더 명확하게 만들 수 있다.리팩터링
을 진행할 때도중간계층
이 과도기적 역할을 할 수있어 개발 프로세스와리팩터링
프로세스가 서로 간섭하지 않고 동시에 진행 될 수 있다.- 단계적으로 리팩터링이 가능하다.
- 리팩터링 프로세스와 개발 프로세스가 서로 충돌할 가능성이 낮아진다.
3. 모듈화와 계층화를 적용한다.
복잡한 시스템을 개발하고 유지할 수 있는 주된 이유는 전체 시스템을 프로세스 스케줄링
, 프로세스 통신
, 메모리 관리
, 가상 파일 시스템
, 네트워크 인터페이스 모듈
등 여러 개의 독립적인 모듈
로 분할하기 때문이다.
모듈화
는 복잡한 시스템을 구축할 때 사용되는 일반적인 수단이다.모듈
은인터페이스
를 통해 통신하며모듈
간의결합도
는 매우 낮다.모듈
은 독립적인클래스 라이브러리
로 개발해야 한다.모듈
은 다른 모듈이 클래스의 내부에 접근할 수 있도록 구현 세부사항을캡슐화
하여,인터페이스
형식으로 제공해야 한다.
모듈화
의 개념은서비스 기반의 아키텍처(SOA)
,마이크로 서비스(MSA)
,클래스 라이브러리
,클래스
와 기능의 설계에 반영된다.
모듈화의 본질은 분할을 통한 제어 이다.
모듈화
외에도 계층화
는 복잡한 시스템을 구축하는 일반적인 수단이며, 복잡한 시스템이 발전할수록 계층화 기술을 최대한 이용해야 한다.
- 각 계층은 구현 세부 사항을
캡슐화
하고 상위 계층에서 사용할추상 인터페이스
를 노출한다. - 다른 계층의 코드에 영향을 주지 않고 각 계층을 다시 구현하거나 업데이트 할 수 있다.
재사용
이 용이하고 특정 비즈니스와 관계 없는 코드는 최대한 하위계층으로 내리고, 수정이 빈번한 특정 비즈니스와 깊게 관련된 코드는 상위 계층으로 올려야한다.
4. 단일 책임 원칙을 준수한다.
단일 책임 원칙
은 높은 응집도
를 달성하기 위한 가장 중요한 지침이다.
- 모듈이나 클래스에 단일 책임이 있는 경우 해당 클래스에 의존하는 클래스와 해당 클래스가 의존하는 클래스의 수가 줄어들고 코드의
결합도
가 낮아진다. 응집도
와결합도
는 서로 독립적인 요소가 아니기 때문에 응집도가 높으면 코드의 결합도가 낮아지게 된다.
5. 구현이 아닌 인터페이스 기반의 프로그래밍을 한다.
인터페이스 기반의 프로그래밍
은 의존성이 있는 두 개의 모듈 또는 클래스 사이에서 어떤 모듈이나 클래스의 변경사항이 다른 모듈 또는 클래스에 영향을 미치지 않는다.
6. 의존성 주입을 활용한다.
의존성 주입
은 모듈 또는 클래스 사이의 강한 결합을 약한 결합으로 바꿀 수 있다.
의존성 주입
이 원래 의존성이 있어야 하는 두 개의 클래스를 의존성이 없는 형태로 바꿀 수 있는 것은 아니다.- 최소한 두 클래스 사이의 결합정도를 원래보다 낮출 수 있으며, 의존하고 있는 클래스를 다른 클래스로 쉽게 바꿀 수도 있다.
7. 상속보다는 합성을 더 많이 사용한다.
상속
은 강한 의존 관계에 해당하여 상위 클래스의 변경은 모든 하위 클래스에 영향을 미친다. 하지만 합성
은 약한 의존관계로 복잡한 상속관계를 합성으로 대체하면 디커플링이 가능해진다.
상속
은인터페이스
,합성
,위임
을 통해 완전히 대체 가능하다.
8. LoD 를 준수한다.
LoD
를 사용하는 목적은 코드의 결합도
를 낮게 유지하기 위해 사용한다.
LoD
에서는 직접 의존성이 없어야 하는 클래스 사이에는 반드시 의존성이 없어야 하며, 의존성이 있는 클래스는 필요한인터페이스
에만 의존해야한다.
'개인공부 > 아키텍처' 카테고리의 다른 글
[ 아키텍처 ] 파이프-필터 아키텍처 (1) | 2023.11.03 |
---|---|
[ 아키텍처 ] 로드밸런싱 패턴 (1) | 2023.10.29 |
[ 아키텍처 ] 클린아키텍처에서의 유스케이스 구현하기 (0) | 2023.08.02 |
[ 아키텍처 ] 클린아키텍처의 구성과 패키지 구조 (0) | 2023.07.24 |
[아키텍처] 클린아키텍처(Ports and Adapters): 왜 클린 아키텍처를 공부하게 되었는가? (0) | 2023.07.20 |