SPARTA 수준별 수업 챌린지반 Day02
자바에서 함수란? (method, function)
입출력? 동작? 행위? 과정?
대화의 전달력 향상
bad case
public void dataProcess() { ... };
good case
public void calculateTotalCount() { ... }
// big function
public void order() {
// small functons
validateOrder();
calculateDiscount();
submitOrder();
}
bad case
public boolean check(int num) {
return num / 1440 >= 1;
}
good case
public boolean isTimeOverOneDay(int minutes) {
int minutesOfDay = 1440;
return minutes % minutesOfDay >= 1;
}
bad case
if (user.isActive() && user.hasValidSubscription() && "PREMIUM".equals(user.getMembership())) {
...
}
good case
if (canAccessPremiumMember(user)) {
...
}
private boolean canAccessPremiumMember(User user) {
return user.isActive() &&
user.hasValidSubscription() &&
user.getMembership() == Membership.PREMIUM;
}
확장성을 고려한 표현
목적어와 함께 표현
// 단일 대화
public void sendWelcomeEmail();
// 확장성 있는 대화
public void sendEmail(EmailType emailType);
함수명에 정답은 없지만, 함수가 필요한 상황에 따라 단어를 적절히 선택해야함
프로그램 종료
public void terminateProcess()
public void stopProcess()
주문 정보 가져오기
public Order retrieveOrder()
public Order getOrder()
유효성 검사
public boolean validateEmail()
public boolean checkEmail()
보편적으로 이해되는 단어 선택(유비쿼터스 도메인 언어) (ubiquot... domain language)
대화 전달력의 핵심
SOLID
Single responsibity principle
Open Close principle
Liskov substitution principle
Interface segregration principle
Dependency inversion princicple
명령형 방식
List<Integer> results = new ArrayList<>();
for (int n : numbers) {
if (n % 2 == 0) {
results.add(n *n);
}
}
int sum = 0;
for (int n : results) {
sum + n;
}
선언적 방식
int sum = numbers.stream()
.filter(n -> n % 2 == 0)
.map(n -> n * n)
.reduce(0, Integer::sum);
public int add(int a, int b) { return a + b; }
함수를 매개변수로 받거나 함수를 결과값으로 반환하는 고차 함수를 사용함으로써 유연한 대화를 이끌어간다.
List<Integer> customNumbers = numbers
.filter(n -> n % 2 == 0)
.map(n -> n * 2)
.collect();
filter, map 등은 대표적인 고차 함수
List<String> reversedAdultCrewNames = crews.stream()
.filter(crew -> 20 < crew.getAge())
.sorted(Comparator.comparingInt(Crew::getAge).reversed())
.map(Crew::getName)
.collect(Collectors.toList());
생성 → 중간 연산 → 최종 연산 형태로 진행됨
Stream을 반환하는 여러 개의 중간 연산을 연속적으로 연결하며, 지연 평가(Lazy Evaluation)를 활용하여 효율적으로 처리
filter(), map(), sort() 등이 있음
각 고차함수는 lambda 식을 통해 연산 결과를 반환
최종 연산은 한 번만 실행되며, 실행 후에는 Stream이 종료되어 추가적인 연산을 할 수 없음
collect(), forEach(), reduce() 등이 있음
boolean existAdultCrew = crews.stream()
.filter(crew -> 20 < crew.getAge())
.findFirst()
.isPresent();
함수형 프로그래밍 방법과 함께 null 안전성을 높이고, 코드의 가독성을 향상시킬 수 있음
java
ExecutorService executor = Executors.newFixedThreadPool(4);
List<Future<Integer>> futures = new ArrayList<>();
for (Integer number : numbers) {
Future<Integer> future = executor.submit(() -> number * 2);
futures.add(future);
}
for (Future<Integer> future : futures) {
System.out.println(future.get());
}
executor.shutdown();
java stream
numbers.parallelStream()
.map(n -> n * 2)
.forEach(System.out::println);
단점
: 가독성이 무조건 좋지만은 않으며, 코드 중단이 불가하다. 또한 디버깅이 불편하다.