지난 2개월간의 인생 리뷰 - 사이드프로젝트 DND
회고

지난 2개월간의 인생 리뷰 - 사이드프로젝트 DND

살면서 가장 주도적으로 살았던 기간이었다.

2개월동안, 마음속에만 품어왔던 도전들을 하나씩 꺼내보았다.

그리고 그 도전들을 하나씩 리뷰해보려고 한다.

 

첫번째 이야기 - 멘토링

 

사이드프로젝트 - DND


8주동안 DND 에서 [쉽고 빠른 약속시간 정하기 - 모두의시간]을 만들었다.

https://www.dnd.ac/

 

DND

프로젝트에 즐거움을, 모두에게 기회를

www.dnd.ac

 

프로젝트 백엔드 레포지토리

 

 

 

시작


프로젝트 아이디어를 정하는 과정에서 여러가지 좋은 의견들이 나왔다. 우리는 8주라는 기간동안 완성할 수 있는지 여부가 가장 중요하다고 판단했고, 개인적으로는 실제로 사용되는 서비스를 만들고 싶었다. 시간 약속을 잡는 불편함은 당장 하고 있던 회의시간을 잡는 중에도 느꼈던 불편함이었고, 살아가면서도 시간약속을 잡아야 할 일도 많았다. 모두가 불편함에 공감하고 있었고 아이디어 채택은 수월하게 진행됐다.

 

 

사람들의 아이디어를 다 들어보고 아이디어마다 서로 디벨롭을 할 수 있는 부분을 같이 찾아가는 시간을 가졌다. 이 때는 최대한 자신의 의견이 존중받는다는 것을 느껴야 더 좋은 아이디어를 낼 수 있다는 것을 알고있기에, 팀원들의 의견을 존중하며 디벨롭을 같이 생각해보는 방향으로 최대한 생각했었다. 

 

 

아침 7시 회의는 실화입니다. - 채민

 

리서치 및 기획


리서치기간에서는 앞으로 진행할 프로젝트의 기획을 구체화 하기 위해 필요한 리서치들을 했다. 기존에 해왔던 프로젝트는 개발자들끼리만 기획하고 구현했었다. 이 서비스가 사용되기 위한 고민을 개발의 관점에서만 고민했었다. 이번에는 디자이너분들과 함께 제대로된 사용자 모델링을 위해 시장조사, 사용자 설문조사 그리고 이 리서치 정보를 토대로 우리 서비스가 어떤 핵심가치를 지녀야할지 뽑아냈다.

 

 

 

인터뷰 응답을 중심으로 인사이트 뽑기

 

 

핵심 인사이트를 뽑아내고 이를 통해 서비스의 핵심가치 정하기

 

 

이 과정이 정말 오래걸리고 회의도 많이했다. 하지만 정말 사용될 서비스를 위해선 꼭 필요한 과정이라고 생각헀다. 기존에 우테코에서 프로젝트를 했을때는 개발자들끼리 이루어진 팀이었기 때문에 기획적인 부분이 부족할 수 밖에 없었다. 그런데 이번에 DND에서 디자이너분들과 함께할 수 있어서 기획적인 부분과 디자인을 체계적으로 진행할 수 있었다. 

 

 

 

 

 

개발


우테코에서 진행한 프로젝트 코드는 우테코 내내 객체지향과 클린코드를 학습한 내용이 잘 적용되지 못했다. 그리고 우테코가 끝나고 추가로 학습한 도메인 중심적인 설계를 적용할 프로젝트가 필요했다. 누구와 개발을 같이 하게될지는 몰랐지만 잘 설득해서 내가 알고있는 지식들을 팀원과 함께 잘 녹여내보기로 생각했다.

 

 

도메인 용어 통일하기

지원플랫폼에서 근무하면서 배웠던 것들 중에서는 도메인 용어를 통일하는 것이 있었다. 디자이너, 개발자들끼리 도메인 용어를 통일하는 것은 도메인주도개발에 국한된이 아니라 그냥 일을 잘하는 방법중에 하나이다. 그래서 와이어프레임 설계단계에서부터 같은 화면이나 기능인데 서로 다르게 말하고 있는 것들을 잡아서 계속 바로잡으려고 했다.

 

 

이게 생각보다 쉽지는 않았다. 회의를 하는중에 "이거는 이거라고 부르는게 정확하지 않을까요?" 라던가, "이렇게 부르는 것은 정확한 명칭이 아닌것 같아요" 라고 말하는 것은 정말 어려웠다. 게다가 이렇게 태클을 걸었으면 정확한 워딩을 내가 짚어주지는 못하고 같이 고민하자고 하고 있으니 회의 시간이 지체되기도 했었다. 같은 화면, 같은 기능을 모두가 동의하는 합리적인 단어로 말하는 것이 이상적이지만 순조롭게 되지는 못했다. 마감기한이 있으니 급한 것들만 짚기는 했지만 그럼에도 남아있는 잘못된 단어들이 있었다. 지나고나서 보면 도메인 용어는 마감기간때문에 미뤄야할 요소가 아닌 것 같다. 지속되는 서비스를 위해서는 꼭 필요한 작업이라고 생각이 든다. 도메인 용어 하나가 잘못되면 개발코드의 변수명도 이상해지고, 사용자가 보는 단어도 달라지는 경우가 있었다. 처음에 잘못되면 이것들은 바꾸기 어려워진다. 그리고 소통의 문제도 생기게 된다. 다시 프로젝트가 재개될때는 도메인 용어 통일에 대해서는 타협하지 않고 같이 정립해 나가야된다고 팀원들을 설득해야겠다고 생각했다.

 

 

 

처음부터 끝까지 TDD

모두의 시간 프로젝트는 처음부터 끝까지 TDD로 진행했다. TDD를 한번도 해보지 못한 백엔드 팀원과 TDD를 진행하는 것이 어려울 것이라고 생각했지만, 페어프로그래밍으로 처음부터 같이 진행하다보니까 생각보다 괜찮았다. 멘토링으로 TDD 강의도 진행한 경험도 있었지만, 팀원분이 배우려는 자세가 너무 잘되어있었고 학습속도도 스펀지처럼 빨랐기 때문인 것 같다. 프로젝트 중반에는 팀원분이 한번 테스트 코드 없이 프로덕션부터 짜보려고 시도했다가 내가 지금 뭘 해야하지 뇌정지가 와서 '아 이래서 TDD 하시는거군요' 하고 스스로 깨달은 뒤 혼자서 TDD를 진행하시는 것을 보면서 역시 야생형 학습법이 나쁘지 않구나라는 것을 느꼈다.

 

요즘 우테코를 수료하고 실제 회사에 들어간 크루들을 보면 회사에서 TDD를 안하고 있다는 크루들을 많이 보았다. 우테코 내내 'TDD는 신이다' 라고 외치던 사람도 회사에 들어가선 'TDD는 사기다' 라고 외친다고도 한다. 그런데 나는 TDD를 몇년간 직접 해보면서 장점과 단점을 확실하게 알아가고 있다. 나는 해보지 않고 사용을 안하는 사람과 다르기 때문에, 장점이 빛날때 하면 되고 단점이 두드러질땐 하지 않으면 된다고 생각한다.

 

JPA 매핑과 DB연결은 최대한 나중에, 우린 객체설계에 집중하자

팀원분께 처음부터 우리는 ERD 설계부터 하는 것이 아닌 도메인 설계부터 하자고 요청했다. 이 부분도 다행히 팀원분이 거부감없이 새로운 것을 받아들일 준비가 되어있어서 수월하게 진행할 수 있었다. 나 조차도 이렇게 진행하는 것이 처음이었고 객체지향설계와 JPA의 장점과 단점을 직접 경험해보자는 생각으로 이렇게 진행했다.

 

일단 테이블설계를 염두에 두지 않고 진행하다보니까 객체설계 자체에만 집중할 수 있었다. 통합테스트 부분은 메모리를 이용한 레포지토리를 임시로 만들어서 진행했다. 나중에 JPA Repository로 사용할 인터페이스의 이름과 스펙을 똑같이 맞춰놓으면 JPA를 추가할때 코드 변경을 최소화할 수 있겠다고 생각했다. 실제로 이 방법은 나중에 JPA 연결할때 예상대로 되는 모습을 보면서 둘 다 신기해했었다.

 

느낀 장점도 있지만, 단점도 느껴졌다. 단점이라기 보다는 어쩔 수 없는 문제를 해결해야 했다. 역시 객체와 테이블간의 패러다임 불일치 문제가 있었다. 객체를 먼저 설계하다보면 List를 쓸 일이 굉장히 많았다. 그런데 테이블은 리스트라는 개념이 없기 때문에 연관관계를 맺기 위해선 Many에 해당하는 쪽에 One의 FK를 걸어주어야 한다. 우리가 사용하고있는 객체를 엔티티로 사용하기 위해서는 List로 되어있는 객체를 신경써주어야 했다. 그리고 이 List를 엔티티에 매핑하려면 3가지 경우의 수를 따져야 했다. 1) OneToMany 단방향, 2) ManyToOne 단방향, 3) ManyToOne 양방향 이 세가지를 각 어떤 상황에 걸어야할지 고민했다.

 

OneToMany 단방향은 영한님의 강의에선 안티패턴이라고 설명해주셨지만, 같은 애그리거트에서 필수로 같이 조회되고 Many쪽의 데이터가 수정될 일이 없다면 충분히 사용해도 된다고 생각했다. 이미 지원플랫폼에서 사용했던 경험도 있다. OneToMany 단방향에서 추가로 신경써주어야 할 것은 불필요한 update 쿼리가 나가는 부분이다. Many부분의 엔티티가 저장되고 FK를 update하기위해 update쿼리가 추가로 나가는 문제가 있다. 하지만 이 쿼리도 없앨 수 있는 방법이 있다. 사실 이 방법이 있기 때문에 OneToMany 단방향을 고려한 것이다. JoinColumn에 nullable=false, updatable=false 을 걸어주면 Hibernate에서 Many가 save될때 FK를 같이 넣어줘서 update쿼리가 추가로 나가지 않는다.

 

ManyToOne 단방향은 지금 코드를 다시 보니까 사용을 하나도 안했다. 아마 애그리거트를 나누다보니까 ManyToOne 단방향을 걸어야할 상황이 나오지 않은 것 같다. 객체를 List로 가지고있지 않다면 사실 연관관계가 필요하지 않는 경우가 있다. 그리고 굳이 FK로 가지는 것 보다는 그냥 id를 필드로 가지고 있어도 될 수 있다. 우리 코드에서는 ManyToOne 단방향보다는 양방향이 걸려있다.

 

ManyToOne 양방향도 안티패턴이라고는 하지만, 우리 코드에서는 쓰였다. 객체를 List로 갖고있는 상태에서 Many 쪽의 데이터를 수정해야할 일이 있고, One을 조회할때 항상 Many까지 같이 필요한 경우에 쓰인다. 이때는 연관관계 편의메서드를 신경써주어야한다. 우리 코드는 일반적인 Team, Member 예제코드 처럼 되어있진 않고 우리만의 비즈니스 코드였기 때문에 편의메서드를 다른 방식으로 구현해야했다. 

 

코드가 어느정도 완성되고나서 JPA를 붙이는 것이 생각보다 어렵지 않았지만 List 매핑하는 부분은 신경을 많이 써주어야했다. 적용할 당시에는 최선의 방법이었지만 나중에 볼때는 제거하기 어려운 레거시가 되어있을 수 있겠다 라는 느낌이 들었다. 대신에 지금의 경험과 고민으로 다음에는 시간을 아낄 수 있게 되었다. N+1 문제 등 해결해야할 여러가지 문제들이 남았지만 차근차근 해결해보려고 한다.

 

 

도메인 중심 설계와 도메인 이벤트 (feat. 단방향 의존성 관리)

우테코가 끝나고 추가로 도메인 중심적으로 사고하는 방법과 의존성을 단방향으로 관리하는 공부를 했었다. 이번 프로젝트에서도 처음부터 의존성 방향을 잘 관리하여 추후에 도메인 단위로 패키지를 구분할 생각으로 진행했다. 객체설계를 하는 단계에서부터 팀원분이랑 같이 고민하면서 설계했다. 요구사항과 도메인이 계속 추가되면서 구조와 설계도 변경이 자주 되었다. 그러면서도 어느정도 묶이는 개념들이 보였다. 이 부분들을 차근차근 애그리거트로 묶어가며 단방향 의존성을 관리했다.

 

계속해서 추가되는 도메인구조를 팀원분과 항상 같이 설계했다.

 

 

 

참여자가 본인의 일정을 수정하면, 그에 따라 좌)일정 등록 현황우)실시간 조율 현황이 바뀌어야 하는 요구사항이 있었다.

좌) 일정 등록 현황 우) 조율 현황

 

이때는 일정 수정에 따라 진행하는 추가적인 로직들을 수행하려면 양방향을 의존해야 하는 상황이었다. 그래서 일정이 수정되면, 일정이 수정되었다는 도메인 이벤트를 발행하고 일정을 알고있는 다른 도메인들이 이벤트를 리슨해 자신의 로직을 수행하도록 만들었다. 이렇게 의존성을 단방향으로 관리했다. 이렇게만 사용한다면 문제가 없었을텐데 굳이 이벤트를 사용하지 않아야할 때도 이벤트를 사용한 부분이 있었다. 이미 의존을 하고 있어서 굳이 이벤트를 사용하지 않아도 되었는데도 이벤트를 사용해서 여러가지 문제가 발생했다.

  1. 이벤트를 사용함으로써 발생하는 추가적인 코드 (RegisterEvent, Listner코드, 이벤트 테스트 등)
  2. 이벤트 객체를 이벤트를 발생한 도메인에 두지 못하고 Listner 쪽에 두어야 하는 점
  3. 코드를 추적하기 어려움

굳이 이벤트를 사용하지 않아도 된다면, 이벤트를 사용하지 않고 해당 코드를 차례로 호출만 해도 위의 문제가 발생하지 않을 뿐만 아니라 더 쉽고 간결하게 코드를 짤 수 있었다.

 

 

인터페이스를 이용해 의존성 역전하기

단방향 의존성을 위해서는 이벤트 뿐만아니라 인터페이스를 이용한 의존성 역전을 할 필요가 있었다. 현재 의존성 방향이 Room(방) -> TimeBlock으로 되어있다. 이 말의 뜻은 Room은 TimeBlock을 알고있어도 되지만, TimeBlock은 Room을 알 수 없다는 뜻이다.

Room(방) -> TimeBlock 의존성 흐름

하지만 TimeBlock이 수정될때 (참여자가 자신이 등록한 시간을 수정할 때) 방의 정보를 확인해 검증을 해야할 필요가 있었다. 방을 생성할때 지정한 마감기한이 지나지 않았는지, 방이 가지고 있는 날짜들과 시간들 안에 포함되는 시간인지 등을 검증해야했다. TimeBlock에서 Room을 직접 불러 호출하게되면 Room <-> TimeBlock의 양방향 의존성이 생기게 되었다. 이를 해결하기 위해서 인터페이스를 통한 의존성 역전을 이용했다. 또, TimeBlock이 Room을 구분하기 위한 RoomUuid를 불변값으로 가지고있게 만들었다.

 

좌) Room, 우) TimeBlock

@Component
@RequiredArgsConstructor
public class RoomTimeValidator implements TimeReplaceValidator {

    private final RoomRepository roomRepository;
    private final TimeProvider timeProvider;

    @Override
    public void validate(String roomUuid, List<AvailableDateTime> availableDateTimes) {
        Room room = getRoomByRoomUuid(roomUuid);
        validateDeadLine(room.getDeadLineOrNull());
        validateContainsAllDates(room, availableDateTimes);
        validateStartAndEndTime(room, availableDateTimes);
    }
    ...
}

 

 

TimeBlock에서는 interface에만 의존하게 한 후, Room에 구현체를 두어서 의존성 역전을 통해 단방향 의존성으로 만들었다.

좌) 양방향 의존, 우) 단방향 의존

 

이번 프로젝트에서는 단방향 의존성에 집착하며 개발했다. 물론 현업에서 DDD를 경험해본 것도 아니고, MSA를 경험해본 것도 아니었지만 이번 프로젝트에서 열심히 집착해보았다. 아직은 단방향 의존성 관리의 장점을 그렇게 크게 느끼지는 못했지만, 어느 도메인을 수정했을때 어느 도메인까지 변경이 전파될 수 있는지는 한 눈에 알 수 있었다. 그래서 추후에 백엔드 팀원과 작업을 나눌때도 최대한 컨플릭트가 나지 않고 변경이 적은 방향으로 업무를 나누기도 편할거라고 생각되었다.

 

 

 

시간 관련 코드 가독성

지난 번 면담시간 예약서비스를 개발했을때 가장 개선하고 싶었던 것이 시간관련된 코드의 가독성이다. 현재 테스트를 돌리고있는 현재시간이 계속 바뀌는 상황이었고, 원하는 시간으로 테스트하고 싶을때도 자유롭게 할 수 없었다. 어느 시간을 기준으로 테스트를 실행하고 있는지 테스트 코드만으로도 파악할 수 있게 만들고 싶었다. 그래서 이번 프로젝트에서는 시간관련 테스트를 최대한 가독성있게 짜서 시간테스트를 읽는 비용을 최소화하기 위해 노력했다.

 

일단은 먼저, 테스트들에서 사용되는 시간의 범위를 미리 정해놓았다. 2월 8~10일, 시간은 11~14시 안에서 테스트를 돌리기로 결정하고 사용되는 시간들의 픽스처를 하나하나 만들면서 진행했다.

변수안에 시간과 날짜를 같이 넣어놔서 해당 픽스처를 사용하는 테스트에서는 변수명만 봐도 어느 시간과 날짜로 테스트를 돌리는지 한 눈에 알 수 있게 만들었다. 

 

11~13시, 9일 10일을 가지고 있는 방
어떤 날짜와 시간을 등록하는지 알 수 있음

어떤 테스트에서 읽어도 어떤 날짜와 시간으로 데이터를 만들고 있는지 한 눈에 알 수 있게 되었다.

 

 

Fake객체를 통한 테스트 시간 변경

인터페이스를 통해 원하는 시간으로 테스트하도록 만들었다. 프로덕션에서는 실제 LocalDateTime.now(), 테스트에서는 우리가 원하는 시간을 반환하도록 만들고 싶었다. 지난 번 프로젝트에서 여러가지 방법을 한번 시도해본 적이 있었다. 1) mockStatic을 이용한 방법, 2) Clock을 mocking 하는 방법, 3) Fake객체를 만드는 방법 이렇게 세가지를 시도했었다. mockStatic은 동시성테스트를 위해 멀티쓰레딩 테스트 환경을 만들때 문제가 생기기도 하고 기본적으로도 static은 mocking하는 것이 안티패턴으로 여겨지기도 했다. 2번과 3번의 방법 두가지를 고민했는데, 사실 어느 것을 선택해도 방식은 비슷했다. 그래서 멘토링때 강의했던 fake 객체 주입방식을 선택해서 진행했다.

 

TimeConfiguration 클래스를 통해 해당 Configuration을 Import한 테스트에서는 Fake 시간이 주입되도록 만들었다. 

 

 

NoUniqueBeanDefinitionException 트러블 슈팅

TimeConfiguration을 만들때 겪었던 트러블슈팅이 하나 있었는데, 구현체를 반환하는 메서드명(@Bean이 붙어있는)을 실제 Bean의 이름과 똑같이 설정해주어야 한다는 것이다. 그렇지 않으면 NoUniqueBeanDefinitionException 예외가 발생한다.

Bean이 유니크 하지 않다는 예외

실제로 빈이 주입될때는 이름이 같은 것이 우선으로 주입된다. 프로덕션에서는 인터페이스에만 의존하기 때문에 TimeProvider를 의존하는데, 이때 스프링은 timeProvider라는 빈을 찾아 주입하려 한다. 처음엔 TimeConfiguration에서 메서드명을 timeProvider가 아닌 fakeTimeProvider로 했었는데, 이때 Bean의 이름이 @Bean 이 달린 메서드명으로 등록된다.

 

timeProvider의 구현체들 중 현재 프로덕션에서는 realTimeProvider가 컴포넌트 스캔에 의해 Bean으로 등록되었고, fakeTimeProvider 또한 Bean으로 등록되었다. 스프링은 timeProvider 라는 이름으로 관리되는 Bean을 우선적으로 주입하려 했지만 해당 이름이 없었고 다른 이름으로 2개의 빈이 띄워져있었다. 그래서 스프링 입장에서는 어떤 빈을 주입할지 모르는 상태였고 그대로 NoUniqueBeanDefinitionException 예외가 발생하게 되는 것이었다.

 

이를 해결하기 위해서는 FakeTimeProvider를 반환하는 메서드 이름을 fakeTimeProvider가 아닌 timeProvider로 바꿔야 했다. 그러면 FakeTimeProvider 구현체는 timeProvider 라는 이름의 빈으로 등록될 것이고 스프링은 이를 우선적으로 주입하게 되는 것이다. 프로덕션 코드에서는 프로덕션에 있는 하나의 Component만 빈으로 등록되기 때문에 신경쓰지 않아도 된다.

timeProvider가 없어 어떤 것을 주입할 지 모름
timeProvider를 우선적으로 주입함

 

 

 

 

 

아직 한참 남은 작업들

코드를 깔끔하게 유지하려 했지만 결국 마지막 주에는 테스트 코드 없이 배포된 코드도 있었고, 쿼리가 말도안되게 많이 나가는 요청도 있었다. 다시 프로젝트가 재개될때는 실배포를 위한 남은 기능을 완성하고, 테스트코드 없이 주석으로만 표시한 코드의 테스트 보충, 쓸데없이 많이 나가는 쿼리개선, 쿼리성능개선을 차례로 수행해야겠다.

 

 

 

 

 

 

너무 잘만난 페어

이번에 팀운이 너무 좋았다. 디자이너와 프론트분들도 잘 만났지만 백엔드 팀원도 잘 만났다. 백엔드는 2명이서 진행했는데, 스프링으로 실제 프로젝트는 처음하는 분이었지만, 흡수력이 굉장히 빨랐다. 몇주동안 만들고 버릴 프로젝트라면 파트를 나눠서 개발했겠지만, 지속해서 개발하고 싶은 마음이 있었다. 그래서 설계는 무조건 같이 진행하고 개발도 대부분 페어로 진행했다. 나눠서 개발하고 코딩컨벤션을 리뷰로 맞추는 시간보다 그냥 페어로 하나씩 같이 진행하는 것이 훨씬 빠를거라고 생각했다. 최대한 개발 스타일을 맞추고 도메인지식이 최대한 나에게 몰리지 않도록 했다. 언제든지 각자 업무를 맡아서 진행할 수 있도록 도메인 지식이 서로 동기화되는 것에 집중했고 코딩컨벤션도 맞춰나갔다. 만약 파트를 나눠서 개발했다면 한명만 빠져도 해당 프로젝트는 발전이 불가능하게 된다. 하지만 우리는 설계부터 같이 진행했기 때문에 누가 빠져도 추가로 코드를 작성할 수 있는 상태이다. 습득력이 빠른 페어덕분에 우테코에서 배워온 좋은 개발문화를 같이 나눌 수 있었고, 내가 부족한 인프라나 알고리즘부분을 페어로부터 배울 수 있었다. 페어를 하면서 서로의 장점을 배우려는 자세를 배웠다. 누군가를 설득하고 설득당하는 법에 대해서 많이 배웠다.

 

 

아쉬운 것

회고를 한번도 진행하지 못했다. 페어와도 못했고, 팀 단위로도 못했다. 다들 바쁜상태로 사이드프로젝트를 참여해서 회고하자고 따로 부르는 것이 미안했다. 그렇다고 회의 끝나고 진행하려해도 다들 너무 피곤해보였다. 그런데 이것도 다 핑계이다. 안바쁘고 안힘든 팀이 어디있을까. 지금 당장은 분위기가 괜찮은것 처럼 보여도 사람이라면 마음 한켠에 말하고 싶은 것들을 그냥 쌓아두고 있는 경우가 많다. 그리고 이런 작은 것들이 쌓여 팀이 위태해진다. 회고는 이런 팀의 지속력을 유지하고 강화시킬 수 있는 도구이다. 그걸 알면서도 안하고 있던 것이 후회된다. 프로젝트가 재개한다면, 최소 일주일에 한번은 회고할 수 있는 시간을 가져보도록 해야할 것 같다. 

 

 

 

 

 

 

앞으로


이제 시작단계가 끝났다. 우리는 실서비스를 출시해야하고 운좋게 좋은 팀원들을 만난만큼 이 팀을 더욱 더 지속시킬 수 있는 방법을 고민해야한다. 8주동안 정신없이 지나갔고 힘든기간이었지만 팀원들 덕분에 웃으면서 데모데이까지 갈 수 있었다. 솔직히 말하면, 연합동아리에서는 사실 팀원들이 이렇게 좋고 잘하는 사람일거라고 기대는 안했었다. 생각보다 대단하고 멋진 사람들, 열심히하고 잘하고 재밌는 사람들이 이렇게 모일거라고 생각도 못했다. 운이 좋았던 것이라고 생각하고 이 팀을 지속하기 위한 고민을 계속해서 해 나가야겠다.

 

 




감사합니다. DND 8기 5조 여러분들 그리고 이세희 코치님도 감사합니다.

 

 

 

 

 

'회고' 카테고리의 다른 글

지난 2개월간의 인생 리뷰 - 멘토링  (12) 2023.03.05
돌아보는 2021  (2) 2021.12.30