variant variable(가변 변수)와 loop 리팩토링 정리
가변 변수를 누적하는 반복문 2case 리팩토링(미리 처리 + if)
📜 제목으로 보기
가변 변수 누적 반복문 [미리처리 + if문] 리팩토링
01 가변변수 누적 + 반복문내 모든 요소가 매번 하는 일을 미리 처리
가변변수 업데이트 이외에 [반복문내 모든 요소에 적용]할 게 있으면, 미리 적용하고 -> 밖에서 적용하게해서 -> 반복문 및 메서드의 파라미터를 바꿔라
-
누적 업데이트 하는 일과 vs 반환하는 일을 분리해야한다.
-
기존
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; }
-
반복문내 모든 요소에 대해
Integer.parseInt( )
를 해야한다면,반복문 진입 전에 하고 -> 반복문을 도는 파라미터를 미리적용한 결과값으로 변경
해야한다. -
미리하는 작업은
메서드 추출
->파라미터 추출
하여,밖에서 일을 마치고 오게 위임
한다- 위쪽의 메서드의 결과물을 파라미터 추출하게 되면, 밖에서 일하게 하여 -> 한번에 한 일만 하게 만들 수 있다.
-
가변컬렉션(method -> add)의 convert나 가변변수의 누적(+=)은 stream으로 바꿀 수 있다.
-
가변 컬렉션을 convert후 add는 stream의 map -> toCollect로 변경할 수 있음.
-
가변 변수의 누적계산은 .reduce( 기본값, 누적연산 메서드(람다식) )으로 대체할 수 있다.
-
-
최종
02 가변변수 누적 + 반복문 + if의 처리
for 문속 if는 추출해 depth 때문에 추출해야하는데, 누적되는 값은 [가변변수 + 업데이트 로직] 포함된 로직이라면, 가변변수를 return하니, [추출로직에 가변변수 없이 순수 업데이트값만 return하도록]변경하자.
가변변수는 어차피 외부에서 업데이트되니, 추출메서드내 가변변수는 밖으로 빼자
-
기존
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); }
-
반복문 내 if는 depth를 만드므로
추출(타객체라면 위임)
해야한다.- 위임(추출)의 첫단추는
메서드()호출부를 더 위쪽 지역변수로 빼서 1개의 외부 context(파라미터)
로 만들어야한다.
- 위임(추출)의 첫단추는
-
이 때,
return문 없는 로직인데 값을 반환
하도록 추출되었다면,위쪽의 가변변수가 포함
된 것이다. -
추출된 메서드에서
가변변수를 받아 return업데이트된 가변변수
가 아니라업데이트는 외부에서하고, 내부에서는 업데이트에 필요한 값만 return
하도록 ->추출메서드 내부에서 가변변수를 삭제
해보자.-
if 만족시 업데이트이외에
if 불만족시 기본값으로 업데이트하여 return을 생각
한다 -
추출한 가변변수를
메서드 시그니쳐에서 삭제
하고업데이트된 가변변수 return
이 아닌업데이트할 값만 return
하도록 수정한다.- 외부에서 어차피 존재하는 가변변수를
값만 받아 외부에서 가변변수 업데이트
하도록 변경한다
- 외부에서 어차피 존재하는 가변변수를
-
가변변수 누적 업데이트시 [추출된 메서드의 반환값]이라면, [mapToInt 등]으로 변환하여 .sum()때리면 된다.
-
외적으로 가변변수의 누적은 스트림으로 대체할 수 있다.
-
일단 누적될 로직은 리팩토링해서 1개의 메서드로 모은다.
-
stream으로 가변변수에 값을 누적한다면
- 원시값 누적이면 .reduce(0 , 연산람다식 )
- 변환된 값 누적이면, mapToXXX( ) -> .sum()을 때리면 된다.
-