개발을 하다보면 공통 요소들이 생기기 마련이다. 여러 객체에서 재사용되어야 하는 객체라던지, 컴포넌트 등 말이다.
개발을 처음 배웠을 때, 중복 코드를 어떻게든 제거하려고 했다.
<sql id="baseQuery">
SELECT
NAME
, ...
FROM
MEMBERS
</sql>
<sql id="coveringIndex">
SELECT
MEMBER_ID
FROM
MEMBERS
<include refid="criteria"/>
</sql
<sql id="pagingAndSorting">
<if test="sortable"> ... </if>
<if test="pageable">
LIMIT #{offset}, #{limit}
</if>
</sql>
<select id="findAll">
<include refid="baseQuery"/> T
<where>
<if test="name != null">
AND T.NAME = #{name}
</if>
...
<include refid="pagingAndSorting"/>
</select>
Jpa를 사용하기 이전 MyBatis를 사용하면서 Mapper XML File에 동적 쿼리를 다닥 붙여서 만들고 뿌듯해했던 기억을 되살려 작성해봤다.
그렇게 배웠고, 그게 나의 개발 방법이었다.
많은 곳에서 재사용이 일어나는 요소들은 공통화를 하고 보통 common
, core
라는 명칭을 가진 패키지, 또는 모듈에 공통 컴포넌트들을 배치시키곤 한다.
그러나 모든 중복 코드를 제거하려는 노력이, 때로는 나의 발목을 잡아왔다.
다른 모듈, 다른 컴포넌트 등에서는 사용되지 않는데, 공통으로 쓸 것이라 생각하고 빼뒀던,
즉 코어 모듈에 배치 되어 있는 녀석을 변경해야할 상황 같이 말이다.
소프트웨어는 항상 변화한다. 변화하지 않는 것은 그 소프트웨어는 수명을 다 한것이다.
변화하지 않는다는건.. 요구사항이 없으니 바뀔 일이 없는 것일 테니까 (너무 완벽해서 건들게 없을 수도?)
현재의 요구사항을 잘 반영하면서 미래에 대한 변화에 대비하는 유연한 설계를 해야 된다.
나를 비롯해, 모든 개발자들이 원하는 이상향일 것이다.
근데, 지금의 나는 공통화를 포기했다.
한가지 예를 들면 admin
과 user
는 표현해야하는 컨텐츠가 다르다.
user
중 role
에 따라 소비하는 컨텐츠가 다른 거다.
데이터적인 측면에서 봤을때 이 둘은 우리 시스템을 사용하는 "사용자"이다.
하지만 시스템적인 측면으로 봤을때는 데이터를 질의하는 조건도, 데이터 시각화도, 심지어 배포 주기도, 성향도 아예 다른 놈들이다.
이렇게 바라봐야하는 컨텐츠는 다르지만 이 공통 영역으로 흘러들어가기 쉬운 요소들이 있다.
일반적으로 Persistence Layer의 테이블은 하나일테고 자연스럽게 core
, common
패키지 혹은 모듈에 배치되곤 하는데,
admin
이건 user
건 뭐 기타 서비스
들이건 얘네들은 이 공통 영역을 다 참조하게 되어 있는 구조다.
사용자 기능을 만들었고 관리자가 사용해야하는 API의 명세가 플래그 한 두개 차이가 난다고 생각해보자.
"이거 사용자쪽 API는 구현 됐는데 관리자 쪽도 만들어달래요 근데 별로 차이가 없어요. 조건 두개만 더 넣어주시면 돼요."
진짜 별 차이 없어서, 메서드 시그니처를 추가해 줄 수도 있을테지.
난 이런 고민을 하고 싶지 않다.
관리자 기능 쪽에 추가 요구사항이 생겨서 테이블의 컬럼이 변경되고 검색조건이 추가가 되었을 때,
다른 서비스들은 왜 알아야 할까? 들여다 보고 싶고 이거 뭐지? 이거 갖다 쓸까? 라는 마음을 유발 시킬까?
그냥 여지 자체를 안주면 되지 않을까? 감추고 싶은 컴포넌트들이 있단 말이다.
스프링을 쓰면 class
의 Access Level
을 열어주고 싶지 않음에도 열어 줄 수 밖에 없고, final
키워드도 붙여줄 수없다.
구현을 감춰줄 수 없기 때문에, 여러 우회 방법을 거치면서 복잡도가 늘어난다.
엔트리 포인트에서 스프링 애플리케이션을 부트스트래핑할 때 핵심 모듈들의 애플리케이션 컨텍스트를 별도로 격리시켜 체리픽한 컨텍스트만 꽂아준다던가
빌드 전략으로 특정 모듈을 runtimeOnly로 컴파일 단계에선 모르게 한다던가
Spring에서 만든 Spring modulith를 써본다던가
현재 나는 똑같은 코드여도 복사해서 써보고 있다. 초기에는 귀찮았는데 발전 방향이 달라질 때 이를 통해 이점을 얻는 부분도 있었다.
그러나 요구사항이 변경되면 두군데를 봐야하는 단점도 있고 내가 여태 개발해온 버릇들 때문에 이질적이고, 귀찮고 이렇게 까지 해야돼? 싶을 때도 있지만
내가 조금 더 귀찮으면 더 변화에 무쌍해지지 않을까? 생각하며 이 악물고 중복코드를 생산하고 있다. 또 개발 스타일이 어떻게 변할지는 모른다. 이거 저거 시도 해보면서 나만의 스타일을 찾아봐야겠다.