TL;DR

  • 임베디드 사물인터넷(IoT) 다대다 데이터 파이프라인에서 Rust 마이크로 트레이트, 과도한 추상화, 과도한 일반화가 구조적 코드 스멜로 나타났으며 중재자(Mediator) 패턴이 이기종 모듈 간 데이터 변환과 패킷 프로토콜을 중앙화하는 해법으로 제시됨
  • 다양한 데이터 채널의 인터페이스에 맞추기 위한 트레이트 구현이 구조체의 원래 정보를 잃게 하고 장식자화된 개발을 초래함
  • 지나치게 많은 구조체·트레이트·제네릭이 서로 비슷한 작은 객체와 복잡한 연결 구조를 만들어 학습과 디버깅을 어렵게 함
  • 장식자(Decorator) 패턴은 객체 정체성 의존과 다수의 소형 객체 구성이라는 문제를 동반할 수 있음
  • 애자일 개발에서는 아키텍처가 부차적 고려나 창발적 속성으로 남을 수 있으며, 때때로 그 창발 결과가 구조적 코드 스멜로 나타남

임베디드 데이터 파이프라인에서 발견한 문제

  • 임베디드 사물인터넷(IoT) 다대다 데이터 파이프라인을 작업하면서 지난 일주일 동안 아키텍처 수준의 “코드 스멜”이라는 직감의 원인을 추적함
  • 시스템을 확장하려 했지만 지나치게 많은 과도한 추상화에 부딪혔고, 다른 팀 구성원들과도 “어떻게 더 나아질 수 있는가”라는 불확실성과 두려움(FUD)이 공유됨
  • 대형 언어 모델(LLM)을 적용하면 적절한 추상화와 추상화 제거를 생성해 시스템이 작동할 수 있지만, 이는 반창고 위에 다시 반창고를 붙이는 방식처럼 느껴짐
  • 관찰된 코드 스멜은 다양한 데이터 채널에서 작동하도록 구조체의 인터페이스를 조정하는 Rust 마이크로 트레이트의 확산임
  • 다만 이는 관찰일 뿐 아직 진단은 아님

장식자화된 개발이라는 진단

  • 과거 멘토가 학습하게 했던 『Design Patterns』의 인쇄본을 다시 살펴보며 문제의 진단을 시도함
  • 트레이트와 과도한 일반화가 개발을 지나치게 장식자화(decoratorized)하는 결과를 낳았다는 진단에 도달함
  • 『Design Patterns』는 장식자 패턴의 문제를 다음과 같이 설명함

1. 장식자와 그 구성 요소는 동일하지 않음. 장식자는 투명한 외피처럼 작동하지만, 객체 정체성 관점에서 장식된 구성 요소는 구성 요소 자체와 동일하지 않음. 따라서 장식자를 사용할 때 객체 정체성에 의존해서는 안 됨.

2. 작은 객체가 많음. 장식자를 사용하는 설계는 서로 비슷해 보이는 작은 객체가 많은 시스템으로 이어지는 경우가 많음. 객체들은 클래스나 변수 값이 아니라 서로 연결된 방식만 다름. 이런 시스템은 구조를 이해하는 사람에게는 쉽게 사용자 정의할 수 있지만, 배우고 디버깅하기 어려울 수 있음.

  • 현재 관찰한 두 가지 코드 스멜은 다음과 같음
  • 구조체가 인터페이스에 맞도록 트레이트 구현을 통해 장식되지만, 그 과정에서 원래 구조체의 정보가 사라짐
  • 구조체·트레이트·제네릭이 지나치게 많아짐

중재자 패턴을 통한 해법

  • 진단 이후의 remediation으로, 서로 다른 여러 모듈 사이의 데이터 변환과 패킷 프로토콜을 정의하는 중앙 지점이 필요함
  • 『Design Patterns』에서 뒤이어 중재자(Mediator) 패턴을 발견함

집단 행동을 별도의 중재자 객체에 캡슐화하면 이러한 문제를 피할 수 있음. 중재자는 객체 그룹의 상호작용을 통제하고 조정하는 책임을 가짐. 중재자는 그룹의 객체들이 서로를 명시적으로 참조하지 않도록 하는 중개자 역할을 함. 객체들은 중재자만 알게 되므로 상호 연결 수가 줄어듦.

  • 중재자 패턴은 이기종 모듈 사이의 상호작용과 데이터 변환을 한곳에서 조정해 객체 간 직접 연결을 줄이는 방향임

팀 내 설계 공유

  • 객체 다이어그램을 그리며 프로젝트 구조를 머릿속에서 명확히 정리함
  • 정리한 설계를 팀에 발표했고, 이를 통해 다른 팀 구성원들의 FUD도 해소됨
  • 팀 리드로서 팀 전체의 불확실성을 해소하는 일이 중요함

애자일 개발과 설계 패턴

  • 일부는 “처음부터 나쁘게 코딩하지 않으면 됨. 설계 패턴은 진부하고 지나치게 규범적임”이라고 말할 수 있음
  • 그러나 현실 세계, 특히 애자일 개발에서는 아키텍처를 부차적으로 고려하거나 창발적 속성으로 남겨둔 채 진전이 이뤄지는 경우가 있음
  • 때때로 그렇게 창발한 아키텍처가 구조적 코드 스멜을 드러냄