[Refactoring] 냄새 13. 반복문
07 Jan 2023해당 포스트는 inflearn의 백기선님의 강의인 리팩토링 을 듣고 정리한 글입니다.
냄새 13. 반복문
- 프로그래밍 언어 초기부터 있었던 반복문은 처음엔 별다른 대안이 없어서 간과했지만 최근 Java와 같은 언어에서 함수형 프로그래밍을 지원하면서 반복문에 비해 더 나은 대안책이 생겼다.
- “반복문을 파이프라인으로 바꾸는 (Replace Loop with Pipeline)” 리팩토링을 적용하면 필터나 맵핑과 같은 파이프라인 기능을 사용해 보다 빠르게 어떤 작업을 하는지 파알할 수 있다.
리팩토링 33. 반복문을 파이프라인으로 바꾸기
- 콜렉션 파이프라인 (자바의 Stream, C#의 LINQ - Language Integrated Query)
- 고전적인 반복문을 파이프라인 오퍼레이션을 사용해 표현하면 코드를 더 명확하게 만들 수 있다.
- 필터 (filter) : 전달받은 조건의 true에 해당하는 데이터만 다음 오퍼레이션으로 전달.
- 맵 (map) : 전달받은 함수를 사용해 입력값을 원하는 출력값으로 변환하여 다음 오퍼레이션으로 전달.
- https://martinfowler.com/articles/refactoring-pipelines.html : 해당 URL에서 여러 예시를 찾아볼 수 있다.
아래의 Author
객체에 있는 반복문을 Stream API 를 이용해 파이프라인으로 치환하는 작업을 해보도록 하자.
- Author
public class Author {
private String company;
private String twitterHandle;
public Author(String company, String twitterHandle) {
this.company = company;
this.twitterHandle = twitterHandle;
}
static public List<String> TwitterHandles(List<Author> authors, String company) {
var result = new ArrayList<String> ();
for (Author a : authors) {
if (a.company.equals(company)) {
var handle = a.twitterHandle;
if (handle != null)
result.add(handle);
}
}
return result;
}
}
테스트코드를 돌려보면 정상으로 돌아가는것을 확인할 수 있다.
그리고 Author
객체의 변환하고자 하는 메소드 TwitterHandles
의 로직을 확인해보자.
List<Author>
를 매개변수로 받아. 반복문을 돌려준다.- 첫번째 조건으로,
Author
객체 내부의company
변수와 동일한지 판별한다. - 첫번째 조건에 부합할 경우,
Author
객체에서twitterHandle
값을 꺼낸다. - 두번째 조건으로, 꺼낸
twitterHandle
값이 null이 아닌지 판별한다. - 두번째 조건에 부합할 경우, List에 담아 반환한다.
Stream API에서 조건은 filter
를 이용하고 데이터의 가공은 map
을 이용한다.
Stream을 통해 변경된 소스는 아래와 같다.
static public List<String> TwitterHandles(List<Author> authors, String company) {
return authors.stream() /* 매개변수로 받은 author을 stream(반복문)통해 가공한다. */
.filter(a -> a.company.equals(company)) /* Author객체 내부의 company 변수와 동일한지 판별 */
.map(a -> a.twitterHandle) /* Author 객체에서 twitterHandle 값을 꺼낸다. */
.filter(t -> t != null) /* 꺼낸 `twitterHandle` 값이 null이 아닌지 판별한다. */
.collect(Collectors.toList()); /*List에 담아 반환한다.*/
}
다시 테스트를 돌려봐 정상적으로 돌아가는지 확인해 보자.