주요글: 도커 시작하기
반응형

동영상 주소: https://youtu.be/ZNDDy77WInY

 

반응형

youtu.be/gd9aeUywGcM

 

반응형

어제 이어 오늘도 사소하게 코드를 정리했다. 정리하기 전에 코드 형태는 다음과 같다.

if(obj.getData().equals("01") || obj.getData().equals("02") || obj.getData().equals("03")) {
    ....
}

문자열이 여러 값 중 하나인지 비교하는 코드이다. 이런 형태의 코드가 곳곳에 있어 어떻게 변경할까 고민하다가 SQL의 in 구문이 떠올라 다음과 같이 변경했다.

if ( Cond.str(obj.getData()).in("01", "02", "03") ) {
    ...
}

코틀린이었다면 확장 함수를 사용해서 더 간결하게 표현할 수 있었을텐데 하는 아쉬움이 살짝 들었지만 컴파일 속도를 생각하면 이것도 괜찮다.

다음처럼 여러 값이 모두 아닌지 비교하는 코드도 빈번하게 출현한다.

if( !obj.getData().contentEquals("01") && !obj.getData().contentEquals("02") ) {
    ....
}

이를 위해 notIn() 메서드도 추가했다.

if ( Cond.str(obj.getData()).notIn("01", "02") ) {
    ...
}

다음은 Str 클래스의 구현 코드다.

public class Cond {
    public static StrCond str(String s) {
        return new StrCond(s);
    }

    public static class StrCond {
        private String value;

        public StrCond(String value) {
            this.value = value;
        }

        public boolean in(String ... values) {
            for (String v : values) {
                if (v.equals(value)) return true;
            }
            return false;
        }

        public boolean notIn(String ... values) {
            for (String v : values) {
                if (v.equals(value)) return false;
            }
            return true;
        }
    }
}

 

  1. 김광수 2021.04.13 11:30

    구현코드를 변경해 보왔습니다. 그런데 Cond<T> 가 별로 의미 없어 보이긴 합니다 😅
    <code>
    public class CondTest {
    @Test
    void testStr() {
    assertThat(new Cond.Str("a").in("a", "b", "c")).isTrue();
    assertThat(new Cond.Str("d").in("a", "b", "c")).isFalse();
    assertThat(new Cond.Str("d").notIn("a", "b", "c")).isTrue();
    assertThat(new Cond.Str("a").notIn("a", "b", "c")).isFalse();
    }

    interface Cond<T> {
    boolean in(T... values);

    default boolean notIn(T... value) {
    return !in(value);
    }

    class Str implements Cond<String> {
    private final String value;

    public Str(String value) {
    this.value = value;
    }

    @Override
    public boolean in(String... values) {
    for (String v : values) {
    if (v.equals(value))
    return true;
    }
    return false;
    }
    }
    class Int implements Cond<Integer> {
    ...
    }
    }
    }
    </code>

반응형

곧 전달 받을 코드를 이리 저리 훑어 보다가 아래 형태 코드가 눈에 띄었다.

// someData.getIdList()는 String 타입으로 "id1|id2|id3"과 같은 형식
List<String> idList = Arrays.stream(someData.getIdList().split("[|]"))
        .collect(Collectors.toList());

split("[|]") 문자열로 검색해 보니 7 군데에서 완전 똑같은 형태의 코드를 사용하고 있다. 중복이 3번 이상 나고 있어서 이를 위한 보조 클래스 Splits을 만들었다.

public class Splits {
    public static List<String> splitByVbar(String str) {
        return Arrays.asList(str.split("[|]"));
    }
}

그리고 검색한 7 곳의 코드를 다음과 같이 바꿨다.

List<String> idList = Splits.splitByVbar(someData.getIdList().split("[|]"));

테스트 코드가 없어서 Splits.splitByVbar()를 사용하는 코드는 테스트를 할 수 없었다. 대신 기존의 분리 코드와 새 분리 코드가 같은 결과를 내는지 확인하는 테스트 코드를 작성했다.

@Test
void same() {
    assertThat(Splits.splitByVbar("1|2|3")).isEqualTo(oldSplitCode("1|2|3"));
    assertThat(Splits.splitByVbar("1|2|3|")).isEqualTo(oldSplitCode("1|2|3|"));
    assertThat(Splits.splitByVbar("|1|2|3|")).isEqualTo(oldSplitCode("|1|2|3"));
    assertThat(Splits.splitByVbar("1|2||3")).isEqualTo(oldSplitCode("1|2||3"));
}

private List<String> oldSplitCode(String str) {
    return Arrays.stream(str.split("[|]")).collect(Collectors.toList());
}

통과 됨을 확인하고 코드를 푸시했다.

+ Recent posts