📜 제목으로 보기

가변 변수 누적 반복문 [미리처리 + if문] 리팩토링

01 가변변수 누적 + 반복문내 모든 요소가 매번 하는 일을 미리 처리

가변변수 업데이트 이외에 [반복문내 모든 요소에 적용]할 게 있으면, 미리 적용하고 -> 밖에서 적용하게해서 -> 반복문 및 메서드의 파라미터를 바꿔라

  • 누적 업데이트 하는 일과 vs 반환하는 일을 분리해야한다.

  • 기존 image-20220729160356475

        private static int convertAndSum(String[] values){
            return sum(values);
        }
      
        private static int sum(String[] values) {
            int result = 0;
            for (final String value : values) {
                result += Integer.parseInt(value);
            }
      
            return result;
        }
    
  1. 반복문내 모든 요소에 대해 Integer.parseInt( )를 해야한다면, 반복문 진입 전에 하고 -> 반복문을 도는 파라미터를 미리적용한 결과값으로 변경해야한다.

    e4b7fd30-c15b-40b8-aa4e-6f03713f97c3

    image-20220729160951043

  2. 미리하는 작업은 메서드 추출 -> 파라미터 추출하여, 밖에서 일을 마치고 오게 위임한다
    • 위쪽의 메서드의 결과물을 파라미터 추출하게 되면, 밖에서 일하게 하여 -> 한번에 한 일만 하게 만들 수 있다. ecceb4c5-2feb-4b30-bdb2-162100461600image-20220729161124179
  3. 가변컬렉션(method -> add)의 convert나 가변변수의 누적(+=)은 stream으로 바꿀 수 있다.

    • 가변 컬렉션을 convert후 add는 stream의 map -> toCollect로 변경할 수 있음.

      a3c09a51-6354-4c0e-a478-86b7d93511be

      image-20220729161715568

    • 가변 변수의 누적계산은 .reduce( 기본값, 누적연산 메서드(람다식) )으로 대체할 수 있다.

      image-20220729162141416

  4. 최종

    image-20220729162222837

02 가변변수 누적 + 반복문 + if의 처리

for 문속 if는 추출해 depth 때문에 추출해야하는데, 누적되는 값은 [가변변수 + 업데이트 로직] 포함된 로직이라면, 가변변수를 return하니, [추출로직에 가변변수 없이 순수 업데이트값만 return하도록]변경하자.

가변변수는 어차피 외부에서 업데이트되니, 추출메서드내 가변변수는 밖으로 빼자

  • 기존

    image-20220729163255763

    public class Lotto {
      
        private final List<LottoNumber> values;
      
        public Lotto(final int... rawNumbers) {
            this(toLottoNumber(rawNumbers));
        }
      
        private static List<LottoNumber> toLottoNumber(final int[] rawNumbers) {
            return Arrays.stream(rawNumbers)
                .mapToObj(LottoNumber::new)
                .collect(Collectors.toList());
        }
      
        public Lotto(final List<LottoNumber> values) {
            this.values = values;
        }
      
        public int calculateMatchCount(final Lotto other) {
            int matchCount = 0;
            for (final LottoNumber lotto : values) {
                if (other.contains(lotto)) {
                    matchCount += 1;
                }
            }
            return matchCount;
        }
      
        public boolean contains(final LottoNumber lottoNumber) {
            return values.contains(lottoNumber);
        }
    
  1. 반복문 내 if는 depth를 만드므로 추출(타객체라면 위임)해야한다.

    • 위임(추출)의 첫단추는 메서드()호출부를 더 위쪽 지역변수로 빼서 1개의 외부 context(파라미터)로 만들어야한다.

    70b0aff7-70d5-4149-a287-5ec133e567cc

    image-20220729163619567

  2. 이 때, return문 없는 로직인데 값을 반환하도록 추출되었다면, 위쪽의 가변변수가 포함된 것이다.

    image-20220729164106674

    image-20220729164124726

  3. 추출된 메서드에서 가변변수를 받아 return업데이트된 가변변수가 아니라 업데이트는 외부에서하고, 내부에서는 업데이트에 필요한 값만 return하도록 -> 추출메서드 내부에서 가변변수를 삭제해보자.

    1. if 만족시 업데이트이외에 if 불만족시 기본값으로 업데이트하여 return을 생각한다

      6e293038-b7a2-4173-99ec-93b512a7f950

      image-20220729170206588

    2. 추출한 가변변수를 메서드 시그니쳐에서 삭제하고 업데이트된 가변변수 return이 아닌 업데이트할 값만 return하도록 수정한다.

      • 외부에서 어차피 존재하는 가변변수를 값만 받아 외부에서 가변변수 업데이트하도록 변경한다

      af3dd5e3-77ff-430e-8bab-d852dbcc3dbb

      image-20220729170519151

      image-20220729170553637

가변변수 누적 업데이트시 [추출된 메서드의 반환값]이라면, [mapToInt 등]으로 변환하여 .sum()때리면 된다.

  1. 외적으로 가변변수의 누적은 스트림으로 대체할 수 있다.

    • 일단 누적될 로직은 리팩토링해서 1개의 메서드로 모은다.

      6e67ff05-fca2-4df0-8483-9b963b678a4a

      image-20220729171257386

    • stream으로 가변변수에 값을 누적한다면

      • 원시값 누적이면 .reduce(0 , 연산람다식 )
      • 변환된 값 누적이면, mapToXXX( ) -> .sum()을 때리면 된다.

      a5c8fd28-0e8f-4b27-9c45-50e45d6414ce

      image-20220729174041392