최근에 구현 레이어의 역할이라는 유튜브 영상과 지속 성장 가능한 소프트웨어를 만들어가는 방법이라는 제목의 블로그를 읽었다. 두 개 모두 Gemini Kim 개발자님의 글이고, 나는 영상과 블로그를 통해서 지속 가능한 소프트웨어를 만드는 법에 대해서 좋은 인사이트를 얻을 수 있었다. Business Logic, Layer, Module을 통해서 지속 가능한 소프트웨어에 대해서 설명하셨고, Business Logic과 Layer에서 알려주신 방법을 직접 내 코드에 적용해보면서 어떤 것을 배웠고, 어떤 것을 느꼈는가에 대해서 이야기 해보고자 한다.
Business Logic 리팩토링
먼저 이러한 작업을 하는 목적은 전적으로 유지 보수성 때문이라는 생각이 들었다. 그래서 유지 보수를 할 필요가 없는 소프트웨어이거나, 이미 충분히 유지 보수성이 뛰어나다 하면, 이러한 리팩토링은 과할 수 있다고 생각했다.
코드에서 비즈니스의 흐름을 쉽게 알아볼 수 있다면 유지 보수하기 매우 뛰어날 것이라는 말에 공감했다. 그래서 나는 비즈니스의 흐름을 쉽게 알아볼 수 없는 코드와 있는 코드를 먼저 비교해봐야겠다고 생각했다.
작성한지 2달정도 되어가는 이 코드를 보고 주요 비즈니스 흐름을 이해하기는 쉽지 않았다. mealList.forEach(deleteList::remove) 가 어떤 동작을 의미하는 지 이해하는데 시간이 꽤 들었다. 물론 저렇게 코드를 다 펼쳐두는 것의 장점도 느꼈다. 코드가 어떻게 동작할 지 바로 볼 수 있는 것이다. 그러나 새로 프로젝트에 참여한 사람이 저 코드를 보게 된다면, 나는 질문 세례를 받을 거라고 확신한다.
그래서 위와 같이 비즈니스 흐름이 보이게 리팩토링 했다. 물론 Implement안으로 들어가게 된다면 위의 코드는 그대로 존재한다. 그러나 다음과 같이 코드를 작성하고나서 나는 비즈니스 흐름을 한 번에 확인할 수 있는 곳이 생겨서 다른 사람들이 내 코드의 이 부분을 본다면 쉽게 이해할 수 있을 것이라고 느꼈다.
코드를 작성하면서 내가 생각하지 못한 다른 곳에서도 장점이 있었다. 이해하기 어려운 코드에 이름을 달 수 있다는 것이다.
다음과 같이 의미를 바로 이해하기 어려운 코드를 Implement로 한 번 감싸는 작업으로,
이렇게 목적을 바로 이해할 수 있는 코드로 변경할 수 있다. 그래서 다음에 이 코드를 봤을 때도 어떤 목적을 가지고 동작하는지 바로 이해할 수 있었다.
Layer 리팩토링
원래는 다름과 같은 Layer를 사용하고 있었다.
블로그에서 추천한 레이어와 비슷하게 위와 같이 변경하였다.
코드에서 레이어를 이렇게 눈에 바로 보이도록 적용해봤다. 다음과 같이 구성했을 때 Implement Layer를 같은 Layer 간에 참조를 가능하게 함으로 재사용성을 높일 수 있다.
그러면서 생각보다 순환 참조가 쉽게 발생했다. 보통 순환 참조가 발생했던 이유는
다음과 같은 read 메서드 때문이었다. 하나의 클래스가 너무 많은 책임을 가지고 있어서 나는 순환참조였고, *Reader, *Appender 등의 여러 클래스로 나누면서 순환참조를 해결할 수 있었다.
다음과 같이 분리를 하면서 Repository를 같은 도메인의 Implement에서만 참조해야하는 지, 아니면 모든 Implement에서 참도해도 되는 지를 고민했다.
같은 도메인에서만 참조할 수 있다면 다음과 같은 구조이다
나는 Repository에 대한 의존이 한 곳으로 모이게 되면서 자연스럽 코드의 응집도가 높아진다고 생각한다. 그래서 결국 유지보수성이 좋아진다고 생각한다.
느낀 점
비즈니스 흐름이 명확하게 보이도록 코드를 작성하는 것은 유지보수에 큰 도움이 된다고 느꼈다. 앞으로 코드를 작성할 때 비즈니스 흐름이 잘 보이는지 고민하면서 작성한다면 더 나은 품질의 코드를 작성할 수 있을 것이라고 생각했다.
ref
https://www.youtube.com/watch?v=D0cEayHkp2U&t=322s
https://geminikims.medium.com/지속-성장-가능한-소프트웨어를-만들어가는-방법-97844c5dab63
'기술고민' 카테고리의 다른 글
???: 빌더 패턴은 필수 값을 받지 못하잖아요. (3) | 2024.03.26 |
---|---|
정팩메, 생성자 고를 때 무엇을 고려해야 할까? (2) | 2024.03.25 |
낙관적 락으로 동시성 이슈 해결하기 (0) | 2024.03.21 |
Java에서 Code Convention 강제 적용 해보기 (2) | 2024.01.18 |
Repository없이 EntityManager 사용하기 (1) | 2023.12.20 |