Ruby로 최소한의 데코레이터 구축하기

Build a minimal decorator with Ruby in 30 minutes - Remi Mercier

작성자
Ruby Weekly
발행일
2025년 06월 12일

핵심 요약

  • 1 Rails 버전 호환성 문제로 `draper` 젬 대신 Ruby로 데코레이터 패턴을 직접 구현하는 방법을 제시합니다.
  • 2 `method_missing`을 활용하여 모델 메서드 위임을 처리하고, `ApplicationDecorator`로 공통 로직을 추상화합니다.
  • 3 Ruby의 `SimpleDelegator`를 사용하여 데코레이터 구현을 극적으로 간소화하는 최종 솔루션을 소개합니다.

도입

이 글은 특정 Rails 버전과의 호환성 문제로 인해 널리 사용되는 `draper` 젬을 사용할 수 없을 때, Ruby 언어의 기본 기능을 사용하여 최소한의 데코레이터 패턴을 직접 구현하는 과정을 상세히 설명합니다. 뷰 관련 로직을 모델에서 분리하여 코드의 응집도를 높이고 유지보수성을 향상시키고자 하는 개발자의 필요성에서 출발하며, 모델에 뷰 계층의 로직이 혼재되는 것을 방지하기 위한 데코레이터의 중요성을 강조합니다.

저자는 Teacher 모델의 available_places에 따라 배경색을 지정하는 colour_coded_availability 메서드를 예시로 들며, 이 뷰 로직을 데코레이터에서 처리해야 한다고 제안합니다. 초기 TeacherDecoratorTeacher 인스턴스를 감싸지만, 뷰에서 모델의 다른 메서드를 호출할 때 NoMethodError가 발생합니다.

이 문제를 해결하기 위해 Ruby의 method_missingrespond_to_missing?을 활용합니다. method_missing을 재정의하여 데코레이터에 정의되지 않은 메서드 호출을 내부 teacher 객체로 public_send를 통해 전달함으로써, 데코레이터가 자신의 메서드와 기본 모델의 공용 메서드를 모두 처리할 수 있게 합니다.

나아가, 이러한 공통 위임 로직을 재사용하기 위해 ApplicationDecorator라는 상위 클래스를 도입합니다. ApplicationDecorator는 객체 초기화 및 method_missing을 통한 메서드 위임 로직을 캡슐화하며, TeacherDecorator는 이를 상속받아 뷰에 특화된 로직만을 구현합니다. alias_method를 사용하여 내부 객체를 teacher로 참조할 수 있게 하여 가독성을 높입니다.

또한, edit_teacher_path(@teacher)와 같은 Rails 헬퍼가 데코레이터 인스턴스를 올바르게 처리하지 못하는 문제를 다룹니다. to_param 메서드를 기본 모델로 위임하여 해결할 수 있지만, 모든 Rails 기본 동작을 수동으로 위임하는 것은 복잡성을 증가시킨다고 지적합니다.

최종적으로 저자는 Ruby 표준 라이브러리의 SimpleDelegator를 활용하는 가장 간결하고 효율적인 방법을 제안합니다. SimpleDelegator는 생성자에 전달된 객체의 모든 공용 메서드 호출을 자동으로 위임하므로, ApplicationDecorator는 복잡한 초기화 및 method_missing 로직 없이 단순히 SimpleDelegator를 상속받는 것만으로 충분해집니다. 이로써 데코레이터 구현이 극적으로 간결해지며, __getobj__ 메서드를 통해 내부 객체에 접근할 수 있습니다.

결론

이 글은 Ruby에서 데코레이터 패턴을 직접 구현하는 과정을 단계별로 명확하게 설명하며, 특히 `method_missing`의 전략적 활용과 Ruby 표준 라이브러리의 `SimpleDelegator`를 통한 최종적인 간결한 구현에 초점을 맞춥니다. 이 접근 방식을 통해 개발자는 Rails의 특정 버전 제약이나 외부 젬에 대한 의존성 없이도 뷰 로직을 모델에서 효과적으로 분리하고, 코드의 응집도를 높이며 전반적인 유지보수성을 향상시킬 수 있음을 보여줍니다. `SimpleDelegator`는 Ruby의 강력한 내장 기능 중 하나로, 데코레이터 패턴을 구현하는 데 있어 매우 유용하고 효율적인 도구임을 재확인시켜 줍니다.

댓글 0

댓글 작성

0/1000
정중하고 건설적인 댓글을 작성해 주세요.

아직 댓글이 없습니다

첫 번째 댓글을 작성해보세요!