Skip to content
isdnetworks
Go back

두 프로젝트가 같은 것을 만들고 있었다

두 프로젝트에 비슷한 화면이 있어서 합치자는 이야기가 나왔다. 둘 다 게시판이었고 한쪽은 공지사항이고 다른 쪽은 커뮤니티 글이었다. 목록과 상세와 글쓰기와 댓글까지 화면 구성이 같았다.

Table of contents

Open Table of contents

겉이 같고 안이 달랐다

한쪽 코드를 복사해서 만든 것이라 비슷할 수밖에 없었다. 합치기 전에 무엇이 다른지 적어 봤다.

                    A(공지)        B(커뮤니티)
쓰는 사람           관리자만       회원 누구나
읽는 사람           전체 공개      로그인 필요
글 수               연 40건        하루 300건
신고 기능           없음           있다
첨부                문서           이미지
검색                제목만         제목·본문·작성자
삭제                관리자         본인 또는 관리자

일곱 가지가 달랐다. 겉이 같고 안이 달랐던 것이다. 목록을 보여 준다는 겉모습만 같고 그 아래에서 실제로 하는 일은 절반쯤만 겹쳤다.

비교 — 합쳤을 때의 그림

합치면 두 쪽의 조건이 다 들어간다.

if ($board->type === 'NOTICE') {
    if (!$user->isAdmin()) throw new Exception('권한 없음');
} else {
    if (!$user->isLogin()) throw new Exception('로그인 필요');
}

$board->typeNOTICE 냐에 따라 isAdmin() 을 보는지 isLogin() 을 보는지가 갈린다. 이런 자리가 일곱 군데 생기고 하나가 늘 때마다 양쪽을 다 봐야 한다.

합치면 코드는 하나가 되지만 조건이 두 배가 된다. 고칠 때마다 다른 쪽이 안 깨지는지를 매번 확인해야 한다. 그래서 전부 합치거나 전부 나누는 두 선택지를 먼저 버렸다.

진짜 같은 것만 뽑았다

전부 다른 것은 아니었다. 같은 것도 있었다.

같은 것
  - 목록에서 쪽 나누기
  - 본문에서 위험한 태그 거르기
  - 첨부 파일 올리고 내려받기
  - 조회 수 세기

이건 어느 쪽에서나 같았다. 이것만 뽑아 냈다.

class BoardHelper {
    public static function paginate($total, $page, $perPage);
    public static function sanitize($html);
    public static function attach($file, $dir);
}

paginate 는 전체 건수와 쪽 번호로 LIMIT 값을 내고 sanitizehtmlspecialchars 로 태그를 걷어 내며 attach 는 올린 파일을 지정한 자리에 둔다. 셋 다 어느 게시판에서 불러도 같은 일을 한다. 화면과 권한은 따로 두고 이것만 같이 썼다.

공통은 BoardHelper 로 빼고 권한과 목록 조회와 화면은 각자 두는 형태가 됐다. 코드 중복이 3분의 1로 줄면서 조건은 안 늘었다. 합칠지 나눌지가 아니라 어디까지 합칠지가 나은 물음이었다.

나중에 갈릴 것을 물어봤다

지금 같아 보여도 앞으로 달라질 것을 물어봤다.

- 커뮤니티에 추천 기능이 들어갈 예정인가   → 예
- 공지에 예약 발행이 들어갈 예정인가       → 예

둘 다 한쪽에만 들어갈 것이었다. 합쳤으면 그때 또 조건이 늘었다. 앞으로 달라질 것이 있으면 지금 같아 보여도 나눠 두는 것이 맞았다.

B 가 A 를 복사해서 만든 것이라 안 쓰는 코드도 남아 있었다.

// B 에는 신고 기능이 있는데 A 에서 복사한 코드에 이런 게 남아 있었다
function checkNoticePeriod() { ... }   // 아무 데서도 안 부른다
$ grep -rn "checkNoticePeriod" --include=*.php .
BoardController.php:212:    function checkNoticePeriod()

BoardController.php 212줄에 정의만 있고 부르는 곳이 없었다. 이런 것이 열한 개였고 전부 지웠다. 복사해서 만든 코드에는 안 쓰는 것이 딸려 온다.

정한 것과 이유도 적어 뒀다.

게시판 A/B 통합 검토 (2014-03)

전부 합치지 않는다. 권한·조회·화면은 따로 둔다.
공통 처리(쪽 나누기·본문 거르기·첨부)만 BoardHelper 로 뺀다.

이유
  쓰는 사람·읽는 사람·글 수·기능이 7가지 다르다.
  합치면 조건 갈림이 7군데 생기고, 하나 고칠 때 양쪽을 봐야 한다.
  앞으로 추천(B)·예약발행(A)이 각각 한쪽에만 들어갈 예정이다.

몇 달 뒤 같은 이야기가 다시 나왔고 이 기록을 보여 주고 끝났다.

정리


Share this post on:

Previous Post
프레임워크가 정해 둔 자리
Next Post
다시 보냈더니 앞부분이 두 번 갔다