리팩토링 33. 반복문을 파이프라인으로 바꾸기
- etc/리팩토링
- 2023. 5. 10.
들어가기 전
이 글은 인프런 백기선님의 강의를 복습하며 작성한 글입니다.
리팩토링 33. 반복문을 파이프라인으로 바꾸기 (Replace Loop with Pipeline)
- Collection 파이프 라인 (자바의 Stream)
- 고전적인 반복문을 파이프라인 오퍼레이션을 사용해 표현하면 코드를 더 명확하게 만들 수 있다. (가독성 향상 도모)
- 필터 (filter): 전달받은 조건의 true에 해당하는 데이터만 다음 오퍼레이션으로 전달.
- 맵 (map): 전달받은 함수를 사용해 입력값을 원하는 출력값으로 변환하여 다음 오퍼레이션으로 전달.
- https://martinfowler.com/articles/refactoring-pipelines.html (더 많은 예시)
'반복문을 파이프라인으로 바꾸기' 리팩토링은 고전적으로 사용되는 반복문을 파이프라인으로 바꾸면서 가독성 개선을 도모하는 리팩토링이다. 이런 작업은 아래 형태로 변환하면서 사용할 수 있다.
- If-Else 문 → Filter() 메서드로 대체
- 객체의 변환 → Map() 메서드로 대체
어떤 관점에서 더 읽기 쉬워지는 걸까? 기본적으로 For 문안에 If나 Else가 Nested되는 경우, 코드를 점점 읽기 어려워지는 경우가 많다. 스트림을 사용하게 되면, 그런 부분들에 대해서는 한결 더 읽기 쉬워진다.
코드 살펴보기
아래 Author 클래스의 TwitterHandles() 메서드를 살펴보자. 이 메서드에서는 for문이 있는데, for문 자체는 문제가 없다. 다만 for문에서 사용되는 로직이 일반적이기 때문에 for문을 Stream으로 바꾸면 가독성이 좋아질 수 있다는 것이다. 아래 코드는 일단은 Nested If문이 여러번 사용되어서 집중해서 읽지 않으면, TwitterHandle() 코드가 하는 일에 대해서 이해하기가 어렵다.
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;
}
}
위의 반복문은 아래와 같은 순서로 리팩토링 할 수 있다.
- 첫번째 If문 → Filter() 메서드를 이용해서 변경
- 변수할당 → Map()을 이용해 처리할 수 있음.
- 두번째 If문 → Filter() 메서드를 이용해 변경. 이 때, Mapping된 변수를 전달.
- result.add() → Collection을 만드는 작업이기 때문에 Collect() 메서드를 이용해 처리.
이 순서대로 리팩토링을 진행하면 아래 코드처럼 변경되게 된다. filter / map / collect 메서드가 무엇을 하는지 알고 있다면 아래 코드는 더 읽기 쉬워진 코드가 된다.
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) {
// 아래 반복문을 파이프라인으로 바꾸기
return authors.stream()
.filter(author -> author.company.equals(company))
.map(author -> author.twitterHandle)
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
}
'etc > 리팩토링' 카테고리의 다른 글
냄새 13. 반복문 (0) | 2023.05.10 |
---|---|
냄새 12. 반복되는 Switch 문 (0) | 2023.05.10 |
리팩토링 32. 조건부 로직을 다형성으로 바꾸기 (0) | 2023.05.10 |
리팩토링 31. 타입 코드를 서브클래스로 바꾸기 (0) | 2023.05.10 |
리팩토링 30. 기본형을 객체로 바꾸기 (0) | 2023.05.10 |