300x250
✍️ 브릿지 패턴, 소개 브릿지 패턴은 하나의 클래스로부터 파생되는 두 가지 개념을 분리하여 각각을 독립적으로 확장하고, 이를 두 개의 컴포넌트로 결합하는 디자인 패턴이다. 이 패턴을 도입하는 대표적인 케이스는 두 가지 다른 속성을 조합하여 하나의 클래스로 표현하는 작업이 반복적으로 발생할 때이다. 브릿지 패턴을 설명하는 대표적인 예시로 도형과 색을 이야기할 수 있다. Shape에서 파생되는 두 가지 개념 도형과 색을 조합하여 하나의 클래스로 표현하다 보면 중복 코드 증가, 코드의 결합도 상승, 기능 수정과 확장에서 문제가 발생한다. 브릿지 패턴은 서로 다른 속성을 클래스로 분리하고, 한 쪽 클래스가 다른 쪽 클래스를 포함하는 컴포지션을 통해 문제를 해결한다. 이 물리적인 클래스 분리로 클라이언트가 직접..
✍️ 악취 25 : 주석 주석이 많다는 것은 코드에 악취가 많다는 방증이기도 하다. 주석이 많이 달린 코드를 리팩토링의 대상으로 선정해서 리팩토링을 적용한다면 코드가 가진 문제점을 해결하면서 동시에 주석이 필요 없어질 수도 혹은 주석의 내용이 간결하고 명확해질 수 있다. 주석이 많이 달린 코드 뭉치는 '함수 추출하기'를 사용해서 별도의 메서드로 분리할 수 있고, 장황하고 긴 이름의 메서드는 '함수 선언부 변경하기'를 적용할 수 있다. 주석에 명시된 시스템의 규약을 '어서션 추가하기'로 변경할 수도 있다. 여기 주석 악취를 해결하기 위한 세 가지 리팩토링 기법이 있다. 1. "함수 추출하기" 주석이 달린 코드 뭉치가 있다면 2. "함수 선언부 변경하기" 주석이 달린 장황하고 긴 이름을 가진 메서드가 있다면..
✍️ 악취 24 : 상속 포기 서브 클래스에 필드와 메서드가 빈약하다면 서브 클래스가 가져야 할 필드나 메서드를 슈퍼클래스에서 가지고 있을 확률이 크다. 서브 클래스를 제거하거나 서브 클래스로 '필드/메서드 내려주기'를 적용하면 문제는 해결된다. 만약 서브 클래스가 슈퍼 클래스의 기능은 재사용 하고 싶지만 인터페이스가 가진 규약은 따르고 싶지 않다면 '슈퍼 클래스 또는 서브 클래스를 위임으로 변경하기'를 고려해야 한다. 여기 상속 포기 악취를 해결하기 위한 두 가지 리팩토링 기법이 있다. 1. '필드/메서드 내려주기' 2. '슈퍼 클래스 또는 서브 클래스를 위임으로 변경하기' 🍊 필드/메서드 내려주기 슈퍼 클래스에서 할당량(Quota)를 선언했고 서브 클래스가 이를 상속을 받는 구조이다. public c..
✍️ 악취 23 : 데이터 클래스 필드와 getter/setter만 가지는 클래스를 '데이터 클래스'라고 한다. 데이터 클래스의 존재는 코드의 위치가 적절하지 않다는 방증이기도 한데, 일반적으로 필드와 필드를 사용하는 메서드는 한 클래스에 모아서 최소한의 정보만 노출하며 제 기능을 제공해야 하기 때문이다. 다만 예외적으로 데이터 전달을 위한 용도라면 필드와 getter 만으로 클래스를 작성할 수 있다. public 필드를 가지고 있다면 '레코드 캡슐화하기'를 적용해 보고, 불필요하게 공개된 필드는 'getter 제거하기'를 변경되지 않아야 할 필드에는 'setter 제거하기'를 통해 외부로 공개되는 정보는 최소화하고 클래스가 제공하는 기능에만 집중하도록 유도할 수 있다. 파편화된 필드와 메서드를 한 클래..
✍️ 악취 22 : 서로 다른 인터페이스의 대안 클래스 유사한 기능과 목적을 가진 클래스가 서로 다른 인터페이스를 구현하고 있다면 그 목적은 유사할지언정 상호 대체가 불가능한 구조로, 다르게 말하면 다형성을 활용할 수 없는 문제점이 발생한다. 비슷한 일을 서로 다른 규악으로 지원한다면 관리 문제도 발생한다. 중복된 인터페이스를 제거하고 '함수 선언 변경하기'와 '함수 옮기기'를 사용해서 하나의 인터페이스만을 구현하도록 구조를 변경할 수 있다. 하지만 인터페이스를 수정할 수 없는 상황도 존재한다. 외부 모듈 혹은 라이브러리를 참조하는 케이스가 그 대표적인 예시이다. 본 포스팅에선 인터페이스의 수정이 불가능한 상황에서 리팩토링을 적용하는 예제를 소개하려 한다. 🍊 예제 : 적용 전 가정해 봅시다. '이메일을..
✍️ 악취 21 : 거대한 클래스 어떤 클래스가 하는 일이 너무 많아지면 필드도 많아지고 필드를 사용하는 메서드도 많아진다. 시간이 지날수록 내부 코드의 결합도는 증가하고 한 클래스에 너무 많은 일을 담당하니 코드를 이해하기도 수정하기도 어려워진다. 단일 책임 원칙을 고수하라는 이유도 바로 이런 문제점 때문이다. 여러 클라이언트가 공통적으로 호출하는 메서드가 있다면 '함수 추출하기'를 만약 여기에 항상 같이 사용되는 변수까지 있다면 '클래스 추출하기'로 리팩토링을 확장할 수 있다. 여러 클래스에 중복된 필드와 중복된 메서드가 있다면 상속을 사용한 '슈퍼 클래스 추출하기'를 적용할 수 있다. 여기 거대한 클래스를 해결하기 위한 두 가지 리팩토링 기법이 있다. 1. "함수 추출하기, 클래스 추출하기" 공통된..