Devlime 재사용 설계로 유지보수성 높이기

Devlime 재사용 설계로 유지보수성 높이기

1. 배경

Devlime 개발은 여러 개발자가 각자의 기능과 도메인을 담당하여 동시에 개발을 진행하는 방식으로 이루어졌습니다. 비젠드(Vizend) 플랫폼을 기반으로 개발되기 때문에 프로젝트 구조나 기본적인 개발 방식은 어느 정도 통일되어 있었으며, 전체적인 아키텍처 역시 잘 정립되어 있었습니다.

그러나 제품 규모가 커지고 기능이 증가하면서 기존 기능을 수정하거나 다른 개발자가 작성한 코드를 분석해야 하는 상황이 점차 많아졌습니다. 이 과정에서 동일하거나 매우 유사한 기능임에도 불구하고 개발자마다 서로 다른 방식으로 구현되어 있는 경우를 자주 발견할 수 있었습니다.

예를 들어 특정 데이터를 조회하는 로직은 여러 화면에서 동일하게 사용되고 있었지만 각 서비스마다 직접 구현되어 있었고, 화면에서 상태를 표시하는 UI 역시 비슷한 기능임에도 서로 다른 스타일과 구조를 사용하고 있었습니다.

초기 개발 단계에서는 이러한 방식이 큰 문제가 되지 않았습니다. 하지만 기능이 증가할수록 중복 코드가 빠르게 늘어났고, 동일한 기능을 수정하기 위해 여러 위치를 찾아 수정해야 하는 상황이 반복적으로 발생하였습니다.

또한 화면마다 표현 방식이 달라 사용자가 느끼는 UI/UX 경험 역시 일관성이 떨어지는 문제가 있었습니다.

이에 따라 단순히 기능을 구현하는 것에 집중하기보다, 반복적으로 사용되는 로직과 UI를 공통화하여 재사용성을 높이고 유지보수 비용을 줄이는 방향으로 개선을 진행하였습니다.

2. 기존 방식의 문제점

2.1 백엔드

백엔드에서는 동일한 기능임에도 개발자마다 구현 방식이 달라 다음과 같은 문제가 발생하였습니다.

첫째, 가독성이 떨어졌습니다. 동일한 기능을 수행하는 코드가 서로 다른 형태로 구현되어 있어 코드를 읽는 사람 입장에서 기능을 이해하는 데 시간이 많이 소요되었습니다.

둘째, 재사용성이 부족했습니다. 특정 라이브러리 API 호출이나 공통 데이터 조회 로직이 여러 서비스에 중복 구현되어 있었습니다. 예를 들어 직원 정보를 조회하는 로직이 여러 서비스에 직접 작성되어 있었습니다.

Member member = memberClient.findMember(citizenId);

이러한 방식은 새로운 기능을 개발할 때마다 동일한 코드를 반복 작성하게 만들었습니다.

셋째, 유지보수 비용이 증가하였습니다. 동일한 기능이 여러 곳에 존재하다 보니 수정이 필요할 경우 모든 위치를 찾아 변경해야 했습니다.

넷째, 오류 발생 가능성이 증가하였습니다. 비슷한 로직임에도 일부 서비스에서는 예외 처리나 검증 로직이 누락되는 경우가 발생하였고, 동일 기능임에도 서로 다른 결과가 반환되는 문제가 발생할 수 있었습니다.

2.2 프론트엔드

프론트엔드에서도 비슷한 문제가 존재하였습니다.

첫째, 동일한 정보를 표현하는 화면이 서로 다른 방식으로 동작하였습니다. 예를 들어 상태(Status), 우선순위(Priority), 타입(Type)과 같은 데이터는 화면마다 각각 다른 방식으로 표시되고 있었습니다.

둘째, UI/UX가 일관되지 않았습니다. 동일한 정보를 보여주는 컴포넌트임에도 화면마다 색상, 스타일, 레이아웃이 다르게 적용되어 있었습니다.

셋째, 반복되는 다국어 처리 로직이 존재하였습니다. Member 객체의 Display Name을 표시할 때마다 각 화면에서 별도의 언어 처리 로직을 작성하고 있었습니다.

넷째, 공통 기능이 재사용되지 않았습니다. 멤버 프로필, 시간 표현, 에러 처리, 패턴 처리 등의 기능이 여러 화면에서 중복 구현되고 있었습니다.

3. 개선 방향 및 설계

문제를 해결하기 위해 먼저 반복적으로 사용되는 기능들을 분석하였습니다. 이 과정에서 공통화 대상은 크게 백엔드와 프론트엔드로 나눌수 있었습니다.

3.1 백엔드 공통화 대상

백엔드에서는 다음 항목을 우선적으로 선정하였습니다.

  • Enum 클래스

  • 라이브러리 클라이언트 활용 로직

  • 공통 조회 로직

  • 반복적으로 사용되는 도메인 함수

  • 공통 Task 로직

3.2 프론트엔드 공통화 대상

프론트엔드에서는 다음 항목을 중심으로 공통화를 진행하였습니다.

  • Enum 표현 방식

  • 상태 및 우선순위 표시 UI

  • 멤버 프로필 UI

  • 다국어 처리 함수

  • Timezone 처리 함수

  • Grid 공통 설정

  • Error 처리

단순히 함수만 공통화하는 것이 아니라 사용자 경험의 일관성을 유지하는 방향으로 설계를 진행하였습니다.

4. 적용 과정

4.1 백엔드 공통 모듈 분리

가장 먼저 반복적으로 사용되는 라이브러리 호출 로직을 공통화하였습니다. 기존에는 각 서비스가 직접 라이브러리를 호출하였습니다. 다음은 간단한 예시 코드입니다.

Member member = memberClient.findMember(citizenId);

이를 Extern 계층으로 분리하였습니다.

@Service
@RequiredArgsConstructor
public class MemberExtern {

    private final MemberClient memberClient;

    public Member getMember(String citizenId) {
        return memberClient.findMember(citizenId);
    }
}

이를 통해 라이브러리 의존성을 한 곳에서 관리할 수 있게 되었으며, 예외 처리 및 후처리 로직도 함께 공통화할 수 있었습니다.

4.2 Enum 표현 방식 개선

기존에는 Enum 값 자체가 화면에 노출되고 있었습니다.

Late
LeftEarly
HolidayWork

하지만 사용자 친화적인 표현이 어렵고, UI 변경 시 도메인에도 영향을 주는 문제가 있었습니다.이를 해결하기 위해 도메인 값과 UI 표현 값을 분리하였습니다.

LeftEarly("Early Leave")

또한 프론트엔드에서는 DisplayName Map을 통해 화면 표현을 관리하도록 개선하였습니다. 이를 통해 화면 변경이 필요하더라도 도메인 모델 수정 없이 대응할 수 있게 되었습니다.

4.3 다국어 처리 공통화

Member 객체의 Display Name을 화면마다 개별적으로 처리하던 방식을 개선하였습니다. 기존에는 각 화면에서 언어를 직접 판단하고 있었습니다.

개선 이후에는 공통 함수를 통해 처리하도록 변경하였습니다.

getMemberDisplayName(member)

이를 통해 다국어 처리 로직을 한 곳에서 관리할 수 있게 되었고, 언어 정책 변경 시 수정 범위를 최소화할 수 있었습니다.

4.4 UI 컴포넌트 공통화

반복적으로 사용되는 멤버 프로필 UI를 공통 컴포넌트로 분리하였습니다.

기존에는 화면마다 Avatar 생성, 이니셜 계산, Tooltip 구성을 각각 구현하고 있었습니다. 개선 이후에는 하나의 컴포넌트만 사용하도록 변경하였습니다. 다음과 같이 특정 UI/UX 요소를 컴포넌트로 묶고 파라미터를 통해 컴포넌트 내 자유도를 높였습니다.

<MemberProfileGroup
  members={members}
  maxVisible={10}
/>

이를 통해 화면 디자인의 통일성을 확보할 수 있었으며, 새로운 화면에서도 동일한 사용자 경험을 제공할 수 있게 되었습니다.

5. 적용 결과

재사용 가능한 코드 설계를 적용한 이후 다음과 같은 효과를 확인할 수 있었습니다.

첫째, 개발 생산성이 향상되었습니다. 기존에는 새로운 기능을 개발할 때마다 비슷한 로직을 다시 구현해야 했지만, 공통 모듈과 컴포넌트를 활용하면서 개발 시간이 크게 감소하였습니다.

둘째, 유지보수성이 향상되었습니다. 공통 로직이 한 곳에 모이면서 수정 시 영향을 받는 범위를 쉽게 파악할 수 있게 되었고, 중복 수정 작업이 줄어들었습니다.

셋째, 코드 품질이 향상되었습니다. 동일 기능에 대해 하나의 구현 방식을 사용하게 되면서 예외 처리 및 검증 로직이 일관되게 적용될 수 있었습니다.

넷째, UI/UX 일관성이 향상되었습니다. 상태 표시, 멤버 정보, 다국어 처리 등 공통 기능을 동일한 방식으로 제공하면서 사용자 경험의 통일성을 확보할 수 있었습니다.

마지막으로 공통화 과정에서 정리한 내용을 노션 문서로 공유하여 팀원들이 동일한 기준으로 개발할 수 있도록 하였습니다. 이를 통해 단순한 코드 재사용을 넘어 팀 전체의 개발 생산성과 유지보수성을 향상시키는 기반을 마련할 수 있었습니다.

Bignow

Site footer