본문 바로가기
가치관 쌓기/프로젝트 회고

트레바리 Notifier 프로젝트 회고하기

by simplify-len 2022. 2. 20.

pragmatic the nature of software development

[Index]

나는 무엇을 개선했는가?

어떤 비지니스 이펙트를 일으켰는가?

새롭게 배울 수 있었던 것은 무엇인가?

아쉬웠던 부분은 어떤 부분인가?

다음 프로젝트에 개선해야될 것은 무엇인가?

 

✅ 나는 무엇을 개선했는가?

📃 문제점

1. 경직된 소프트웨어

  • 다른 규칙의 SMS 규칙은 불가하다.
  • 문자 발송시기 조정이 불가하다.
  • 일시적으로 SMS 규칙을 중지하기 원한다.
2. 불명확한 시스템
  • Google Sheet 에서 문자 템플릿을 관리하고 있지만, Fresh 한 상태가 아니다. 이또한 코드로 연결되어 있지 않다.
  • 매번 Senders 웹페이지에 접속하여 발신 내역을 조회하고 / 인증문자을 전송을 확인한다.
3. 잦은 버그
  • AWS에 의존적인 부분에 대해서 전체 테스트가 불가능하기 때문에 배포하고 나서 기도한다.
  • 일시적으로 특정 규칙을 중지하고 다시 원복을 잊어버린다.

🌊 개선 방향

1. 시스템 내에서 발신 내역을 조회하고 송신할 수 있다.

2. 문자메세지 뿐만 아니라 Slack, E-MAIL 등 외부 시스템에 의존하지 않는 확장성있는 시스템을 만든다.

3. Notification( ex, 문자메세지, Slack, E-mail...) 을 유연한 규칙을 적용할 수 있는 기초를 쌓는다.

 

어떤 비지니스 이펙트를 일으켰는가?

1. 크루는 더이상 문자발신내역을 확인하기 위해 Senders 홈페이지에 접근하지 않음으로써, 업무 피로도가 줄었다.

2. 유저에게 SMS 뿐만 아니라, Email, kakao biz 등의 Notification을 전달할 수 있는 확장성있는 시스템이 개발되었다.

 

✅ 새롭게 배울 수 있었던 것은 무엇인가?

1. 일을 작게 쪼개 팀원분들에게 역할을 부여할 수 있다.

> 동작하는 작은 소프트웨어를 쿽하게 개발합니다. 이때 사용될 수 있는 인터페이스를 보여준다. 그리고 그 인터페이스가 어떤 역할을 하는지 함께 이해하며, Tasks 를 만들어 냅니다. 당연히 쿽하게 만들었기 때문에 변경될 수 있고, 잘못될 수 있습니다. 인터페이스를 검증하는 과정에서 유연하게 모델링을 변경하며 팀원분들과 공유합니다.

 

2. '작동하는 소프트웨어를 보여주세요.' 를 이해할 수 있다.

> 핵심은 'Actor 에서 가치를 전달한다' 입니다. 이는 애자일 선언 이면의 원칙중 일부에서 표현되는데, 이렇게 하는 이유는 소프트웨어의 핵심은 바로 Actor 가 원하는 것을 빠르게 충족시켜주기 위해서이다.

애자일 선언 이면의 원칙

3. '빨리하기' 보다 해결하고자 하는 것을 '쉽게 그리고 속도를 가질 수 있는 것'에 집중한다.

> 프로젝트를 진행하면서 시간에 쫓기듯 개발하는 의도치 않는 순간들이 주기적으로 발생했다. Iterator 기본 개념을 증명하기 위해서 구현체에 의존한 형태를 만들어 놓고 개념을 증명하기 위해 접근했다. 이는 '빨리하기' 위한 잘못된 방향으로 나아간 것이다. 어떻게 접근해야 될까? 구현체에 의존하는 형태가 아니라, 개념이 코드로 표현되어져야 한다.

 

4. 구현체에 의존하지 않는 인터페이스의 중요성

> 이번 프로젝트의 핵심은 확장성 이라는 단어에 있다. 시스템이 변경에는 닫혀있고, 확장에 열려있을 수 있는지 끊임없이 고민하면서 인터페이스가 가져다주는 이점이 무엇인지 이해할 수 있었다.

함수는 한 가지를 해야 한다. 그 한 가지를 잘 해야 한다. 한 가지만을 해야 한다. 
...
지정된 함수 이름 아래에서 추상화 수준이 하나인 단계만 수행한다면 그 함수는 한 가지 작업만 한다. 어쨋거나 우리가 함수를 만드는 이유는 큰 개념을 다음 추상화 수준에서 여러 단계로 나눠 수행하기 위해서가 아니던가?
                                                                                  - 3장 함수 (클린 코드)

5. 객체가 가진 책임을 끊임없이 고민한다. 나아가 새로운 도메인을 도출한다.

 

6. 테스트 코드에 개선 가능한 악취를 느낄수 있다.

    @Test
    void execute_with_single_notificationTarget() {
        given(targetProvider.getTargets()).willReturn(List.of(target1));
        given(factory.findBy(any())).willReturn(notificator);
        given(notificator.execute(target1)).willReturn(requestSuccess);

        sut.execute();

        verify(targetProvider).getTargets();
        verify(factory).findBy(any());
        verify(notificator).execute(any(NotificationTarget.class));
        verify(successHandler).onHandle(requestSuccess);
        verifyNoMoreInteractions(failHandler);
    }

> 무엇을 하려는 테스트 코드일까? 

행위를 테스트하는 코드이지만, 너무 많은 행위를 검증한다. 이말은 즉슨 Product 의 코드가 조그만 변경되더라도 많은 테스트 코드가 실패될 수 있음을 의미한다. 이는 곧 메소드 하나는 한 가지 역할을 해야 하는 SRP를 위반한다.

이것은 악취다. 어떻게 해야 하는가? 

 

execute() 메소드가 책임져야할 부분을 명확히 정의한다. 위 테스트 코드의 execute() 는 notificator 를 찾고 찾은 notificator 를 실행하는 것이 가장 핵심 목적이다.

 또한 handler 에 대해서도 resulthandler 를 만들어 책임을 위임할 수 있다. 

 

테스트 코드는 프로덕트 코드를 사용하는 첫번째 클라이언트로 리팩토링의 악취를 느낄 수 있도록 도와줍니다.

 

7. 의미없는 도메인 의존 서비스는 단지 '행위'에 불과하므로, 앙꼬 없는 단팥빵과 동일하다.

> 아주 흔한 예시이다. DB 에 저장하기 위한 객체로 EnvelopNotification 이라는 클래스를 생성했다. 그리고 이 객체를 repository 를 활용해 저장하기 위해서 EnvelopNotificationService 를 만든다. 

 

이 행위는 Spring Boot 를 사용하는 개발자라면 관례처럼 거부감없이 받아들여진다. 이것이 맞을까? EnvelopNotificationService는 DB에 저장하기 위한 용도인가? 고민해보자. 개인적으로 나는 이 Service 클래스가 가진 이유를 납득하기 어렵다. DB에 저장하기 위해 Service 클래스를 만드는 건 객체지향적으로 바라봤을때 Service 클래스가 어떤 의미를 가지고 있는 걸까? 심지어 Service 클래스 메소드 이름마저 save 라면? 이는 잠재적으로 더 큰 문제에 만들어 낸다. Service 클래스에 책임을 부여할 수 있는 이름을 가져야하지 않을까? 만약 DB save 하는 상황이라면, 왜 save 를 하는 것이고- save 가 의미하는 바가 무엇인지 표현되어야 한다.

 

8. 멀티 모듈로 개발시 패키지에 대한 중요성을 이해할 수 있다.

개발의 막바지로 도달했을 때, 총 5개의 모듈 중 도메인 모듈은 나머지 4개 모듈이 모두 의존을 받게 된다. 이때 정상적으로 bean 주입이 되지 않는 이슈를 맞닥드렸다. 이곳에 많은 내용을 참고했었다.

 

✅ 잘한 부분은 어떤 부분인가?

1. 지연없이 릴리즈까지 자연스럽게 완료했다.

2. 시시각각에 변화되는 아키텍쳐 모델링을 유연하게 대처했다.

3. 오로지 비지니스에 집중할 수 있었다.

 

✅ 아쉬웠던 부분은 어떤 부분인가?

1. 팀원에 대한 믿음이 줄어들고, 의심이 도졌다.

2. 끈질기게 개발하지 못했다.

3. 한 가지 일에 집중하지 못했다.

4. 시간 관리에 실패했다.

5. 이슈 관리에 실패했다. 

6. 기술적인 Try 를 단 하나도 하지 못했다.

 

✅ 다음 프로젝트에 개선해야될 것은 무엇인가?

1. 행과 열의 개념을 기억하여 앞으로 나아갈 때는 행/열 개념을 끊임없이 고민하자.

2. Next로 무엇을 해야하는지 고민해야 한다.

3. '빨리 개발하기' 보다는 '찬찬히 쉬운의 개발' 을해야 한다.

댓글