Ch.8 강한 결합: 복잡하게 얽혀서 풀 수 없는 구조

텐저린티·2023년 7월 17일
0
post-thumbnail
💡 결합도
  • 모듈(클래스, 패키지, etc) 사이 의존도를 나타내는 지표
  • 강한 결합
    • 어떤 클래스가 다른 클래스에 많이 의존하고 있는 구조
  • 느슨한 결합
💡 책무
  • 자신이 해야 하는 일
  • 하지 않으면 안 되는 임무

8.1 결합도와 책무

단일 책임 원칙 (SRP)

클래스가 담당하는 책임은 하나로 제한해야 한다.

  • 소프트웨어 책임
    • 자신의 관심사와 관련해서 정상적으로 동작하도록 제어하는 것
  • SRP를 지키도록 노력하는 방법 = 책임을 잘 고려해서 설계
  • SRP를 지키면 느슨한 결합 구조
    • 관심사에 따라 분리해서 독립되어 있는 구조
    • 관련 사양이 변경되어도 서로 영향을 주지 않는 구조

DRY 원칙의 잘못된 적용

모든 지식은 시스템 내에서 단 한 번만, 애매하지 않고, 권위 있게 표현되어야 한다.

  • 하지만!! → 같은 로직, 비슷한 로직이라도 개념이 다르면 중복을 허용해야 함
  • 개념적으로 다른 것까지 무리하게 중복 제거 → 강한 결합 상태
  • 비즈니스 지식
    • 소프트웨어에서 다루는 비즈니스 개념
    • 할인, 관심 상품, 크리스마스 캠페인 등등 모두 개념
  • 일반 로직이 아님을 알게 된 순간 (개념이 다르다는 것을 알게 된 순간) 곧바로 일반화 했던 것을 나눠야 함

8.2 다양한 강한 결합 사례

상속 관련 강한 결합

  • 상속은 주의깊게 다루지 않으면 강합 결합 유발
  • 상속관계에서 서브 클래스는 슈퍼 클래스에 크게 의존
  • 슈퍼 클래스는 서브 클래스 신경쓰지 않고 변경됨
  • 변경 시 서로의 내용을 알아야 하는 상속 구조는 피하는 것이 좋음
  • 상속보다 컴포지션 구조
    • 사용하고 싶은 클래스를 private 인스턴스 변수로 갖고 시작하는 구조

    • 서브 - 슈퍼 클래스가 서로 구조를 몰라도 되기 때문에 결합도가 줄어듬

    • PhysicalAttack 로직 변경되도 FighterPhysicalAttack 클래스는 영향을 적게 받음

      class FighterPhysicalAttack {
      		private final PhysicalAttack physicalAttack;
      
      		int singleAttackDamage() {
      				return physicalAttack.singleAttackDamage() + 20;
      		}
      		
      		int doubleAttackDamage() {
      				return physicalAttack.doubleAttackDamage() + 10;
      		}
      }
  • 상속보다 템플릿 메소드 패턴
    • 상속받는 쪽에서 차이가 있는 로직만 구현
  • 상속 사용 시 고려할 사항
    • SRP 원칙 준수 여부
    • 값 객체 사용 가능한가?
    • 컴포지션을 사용해볼까?
    • 정 사용해야 한다면, 템플릿 메소드 패턴을 적용해볼까?

인스턴스 변수 별로 클래스 분할이 가능한 로직

  • 클래스를 잘 분리하려면, 각 인스턴스 변수와 메소드가 무엇과 관련 있는지 잘 파악해야 함.
    • 관련 있는 (인스턴스 - 메소드) 로 클래스를 분리하면 된다.
    • Jig 같은 영향 스케치 도구를 이용해보는 것도 좋은 방법

특별한 이유없이 public 금지

  • 접근지정자를 이용해서 모듈 간 불필요한 의존관계를 제거해야 한다.
public모든 클래스에서 접근 가능
protected같은 클래스, 상속받은 클래스에서 접근 가능
(default)같은 패키지 내 클래스에서 접근 가능
private같은 클래스에서 접근 가능
  • 패키지 안에서는 밀집한 클래스끼리 응집하게 설계
    • 그래서 기본값이 package private인 것

private 메소드가 많다 = 클래스 책임이 많다

높은 응집도를 오해해서 생기는 강한 결합

  • 자주 발생
  • 각각의 개념을 잘 분리
  • 결과적으로, 느슨한 결합 + 높은 응집도 설계가 좋은 설계!
  • 응집도 높이는 설계할 때 다른 개념이 섞이는 지 잘 판단

스마트 UI

  • 화면 표시 담당 클래스 중에서 화면 표시와 직접 관련 없는 책무가 구현되어 있는 클래스
  • 화면 표시 책무, 그렇지 않은 책무가 강하게 결합

거대 데이터 클래스

  • 전역변수와 같은 성질
  • 동기화로 인한 성능 저하 등 발생

트랜잭션 스크립트 패턴

  • 메소드 내부에 일련 처리가 하나하나 길게 작성되어 있는 구조
  • 데이터 클래스, 데이터 사용 클래스가 분리되어 있는 경우 자주 발생

갓 클래스

  • 하나의 클래스 내부에 수천, 수만 로직 담아 책임이 막중한 클래스

8.3 강한 결합 클래스 대처법

  • OOP 설계 준수 → SRP 준수
  • 책임별로 클래스 분할
  • 조기 리턴
  • 전략 패턴
  • 일급 컬렉션
  • 목적 중심 이름 설계
profile
개발하고 말테야

0개의 댓글

관련 채용 정보