클린코드란 무엇이고, Stream(스트림)을 어떻게 활용할까?
좋은 코드다. 좋은 코드에 대한 기준은 상황과 환경 시기, 방법론에 따라 다르게 판단될 수 있다.
딱 잘라서 무엇이라고 정의할 수는 없다.
그렇다고 마냥 굴러가는 코드는 좋은 코드가 아니다.
여러가지 의견이 있을 수 있다.
하지만, 이것은 분명하다고 할 수 있다.
"Clean code does one thing well.”
클린 코드는 하나의 일을 잘 하는 코드이다.
- Bjarne Stroustrup, inventor of ‘C++
“Clean code is simple and direct."
클린 코드는 간결하며, 직접적이다.
- Grady Booch, author of ‘Object-Oriented Analysis and Design with Applications’
결국 클린코드는 간결하고, 단순하며, 어떤 일을 처리하는데 복잡하지 않고 모호하지 않으며 하나의 역할을 잘 수행하는 것.
즉 가독성이 좋고 원하는 로직을 빠르게 찾고 이해할 수 있는, 모든 팀원이 이해하고 쉽게 알 수 있는 코드이다.
그만큼 가독성이 올라가면 코드파악, 코드리뷰, 디버깅에도 시간이 단축되기 때문.
- 읽기 쉽고 명확한 코드 작성
- 간결한 함수와 메서드 작성
- 코드 중복 최소화
- 의미 있는 이름 사용
- 함수와 클래스 크기 제어
- 효과적인 주석 사용
- 오류보다는 예외처리
- 테스트 주도 개발(TDD) 촉진
그럼 클린코드를 위해 Stream을 어떻게 활용해야 할까?
Stream (스트림) 이란 무엇일까?
자바 8 에서부터 추가 된 것으로 스트림을 사용하지 않고 컬렉션을 다루는 방법은 외부 반복을 사용하는 것이었다.
for, foreach 등등… 간단하고 직관적이지만 로직이 복잡해지면 코드 양도 많아지고 루프를 여러번 돌리는 경우도 있어
가독성 또한 떨어진다.
하지만 ! 스트림 그래 너라면 !
더 간결하고 가독성도 좋으면서 배열 또는 컬렉션에서 원하는 결과를 필터링 하고 가공하여 결과를 얻을 수 있다.
람다를 이용해서 코드양도 줄일 수 있다는 것이지요! 👍
그래서 Stream (이하 스트림이라 함) 이 뭔데 뭐냐고?
우리가 야구 팀에서 타자 중에 팀 내 타율 5위 내에 왼손 타자만 뽑는 다고 고민해보자.
그러면 야구 팀에서 타자 리스트 추출 → 정렬 하여 5위 내 타자 추출 → 왼손타자 추출
대략 이렇게 노가다로 뽑아야 할지도 모른다.
그러다 보면 중간 중간 가비지 변수도 생길 수 있고, 소스가 간결하지 못하게 된다.
하지만 스트림을 쓴다면 !?
filter, sorted, limit 를 활용해서 아주 간결하게 표기 할 수 있다.
(예제는 모두 짬에서 나오는 바이브가 있기 때문에 추가 하지 않았습니다.)
filter, map, reduce, find, match, sort, limit 등으로 데이터를 처리 하고, 순차 또는 병렬 실행이 가능하다.
컬렉션이 데이터라고 한다면, 스트림은 데이터 계산 또는 조작 이라고 볼 수 있다.
스트림 특징
연산간의 연결
스트림 연산은 연산끼리 연결되어 스트림 자신을 반환한다.
내부반복
명시적으로 반복자 즉 for, foreach 등을 사용하여 반복하는 컬렉션과 다르게 스트림은 내부 반복을 지원한다.
컬렉션과 스트림의 차이
컬렉션 : 현재 자료구조가 포함하는 모든 값을 메모리에 저장하는 자료 구조
스트림 : 요청 할 때만 요소를 계산 하는 자료구조로 사용자가 요청하는 값만 추출하는 것이 스트림 핵심
반복 처리
컬렉션 : 사용자가 직접 요소를 반복해야 한다. 외부 반복이라 함.
스트림 : 내부 반복을 사용하기 때문에 어떤 작업을 수행할지만 지정.
스트림 연산
중간 연산
스트림을 연결할 수 있는 연산으로 filter, sorted 같은 연산이 있다. 중간 연산은 다른 스트림을 반환하기 때문에 다음과 같이 여러 중간 연산을 연결하여 질의를 만들 수 있다.
중간 연산은 해당 스트림 파이프라인에 실행하기 전까지는 아무 연산도 실행하지 않는다는 특징이 있으며, 중간 연산을 모두 합친 다음에 합쳐진 중간 연산을 최종 연산으로 한번에 처리한다.
최종 연산
스트림을 닫는 연산으로, 보통 최종 연산에 의해 List, Integer 등등 스트림 이외의 결과가 반환된다.
예)
members.stream()
.filter(...) // 중간연산
.map(...) // 중간연산
.limit(...) // 중간연산
.collect(toList()); // 최종연산
결론 : 간결하고 가독성 좋은 코드가 협업 시에는 더욱 중요하다. 그렇기에 스트림은 매우 유용하다.
현재 다양한 서비스에도 매우 잘 활용하고 있기 때문에 본인의 환경에 맞게 잘 활용할 수 있다.