생각하며 개발하기.

김준석·2023년 2월 6일

기계적으로 코딩을 하고, 다시 내 코드를 돌아봤을 때 불 필요하게 남용된 메서드들과 하나의 메서드에서 여러 일을 하고 있는 경우들이 많이 보였다.
늘 코딩을 할 때 'convention에 맞춰 작성해야지!' 라고 생각해둔 상태로 시작하지만, 막상 만들다보면 여러 이유(습관, 진짜 아무생각 없이, 오류를 피하려고..?)로 인해 지저분해지고 복잡해진다. 사실, 누군가의 도움이나 리뷰어 없이 혼자 개발을 하다보면 어쩔 수 없는 부분이기도 하다.(개인적으로!) 내가 내 코드를 봤을 땐 이상이 없어보이니까. 꾸준히 찾아보고 생각해볼 과제인 것 같다.


향수 데이터들을 크롤링하고 CSV파일에서 불러와 DB에 저장하기 위해 만든 코드이다.
DB에 저장하는 코드 말고, CSV파일에서 각 특징별 데이터들을 List에 담을 생각을 하고 구현했다.

    public List<String> extractPerfumeName() throws IOException {
        splitPerfumeData();
        List<String> testList = new ArrayList<>();
        for (int i = 0; i < perfumeListTest.size(); i += COLUMN_LENGTH) {
            testList.add(perfumeListTest.get(i));
        }

        return testList;
    }

    public List<String> extractPerfumeFeature() throws IOException {
        splitPerfumeData();
        List<String> testList = new ArrayList<>();
        for (int i = 1; i < perfumeListTest.size(); i += COLUMN_LENGTH) {
            testList.add(perfumeListTest.get(i));
        }

        return testList;
    }

    public List<String> extractPerfumeBrand() throws IOException {
        splitPerfumeData();
        List<String> testList = new ArrayList<>();
        for (int i = 2; i < perfumeListTest.size(); i += COLUMN_LENGTH) {
            testList.add(perfumeListTest.get(i));
        }

        return testList;
    }

    public List<String> extractPerfumeImageUrl() throws IOException {
        splitPerfumeData();
        List<String> testList = new ArrayList<>();
        for (int i = 3; i < perfumeListTest.size(); i += COLUMN_LENGTH) {
            testList.add(perfumeListTest.get(i));
        }

        return testList;
    }

    public PerfumeList extractAllPerfumeData(PerfumeList perfumeList) throws IOException {
        perfumeList = perfumeList.builder().perfumeName(extractPerfumeName())
                .perfumeFeature(extractPerfumeFeature())
                .perfumeBrand(extractPerfumeBrand())
                .perfumeImageUrl(extractPerfumeImageUrl())
                .build();
        return perfumeList;
    }

코드를 기계적으로 다 짜고 나니 생각이 들었다. 그리고 현타가 왔다..
1. 전부 같은 구조이다. 굳이 왜 나눠놨을까?
2. 중복이 너무 많다.
(각 메서드마다 선언된 똑같은 testList, 조금 다르지만 거의 비슷한 반복문)
큰 현타가 왔고.. 다시 줄여나갔다.


수정한 코드

    public List<String> extractPerfumeData(int columnNumber) throws IOException {
        splitPerfumeData();
        List<String> testList = new ArrayList<>();
        for (int i = columnNumber ; i < perfumeListTest.size(); i += COLUMN_LENGTH) {
            testList.add(perfumeListTest.get(i));
        }

        return testList;
    }

    public PerfumeList extractAllPerfumeData(PerfumeList perfumeList) throws IOException {
        perfumeList = perfumeList.builder().perfumeName(extractPerfumeData(NAME_COLUMN))
                .perfumeFeature(extractPerfumeData(FEATURE_COLUMN))
                .perfumeBrand(extractPerfumeData(BRAND_COLUMN))
                .perfumeImageUrl(extractPerfumeData(IMAGE_URL_COLUMN))
                .build();
        return perfumeList;
    }

name, brand, feature, imageurl로 나뉜 각 메서드를 하나로 통합했다.
대신, 매직넘버였던 for문의 i 값 (0,1,2,3) 대신에 매개변수로 columnNumber를 받는 방법을 선택했다.
결국 최종적으로 추출해내는 extractAllPerfumeData에서 이 메서드에 각기 다른 상수를 넣으면서 해결했고, 보기에도 Name, Feature 데이터를 추출해내는 메서드군! 이라고 판단할 수 있을 것이라 생각한다.
향수 데이터 말고 다른 데이터도 크롤링해야 하는데, 결국 새로 코드를 세울 필요 없이 Column값만 조절하여 그대로 사용할 수 있을 것이다.

누군가는 미리 생각해두고 효율적으로 만들겠지만 나는 그러지 못했다. 더 배우고 덜 배우고의 차이보다, 그냥 생각을 어디까지 했냐의 차이인 것 같다. 반성하세요 돌석석돌!

profile
기록하면서 성장하기!

0개의 댓글