PHpullh
학습 라이브러리/Java/부수 효과 관리

JAVA · 함수형/Stream

부수 효과 관리

I/O 등의 부수 효과를 순수 로직과 분리하는 전략을 배웁니다.

함수형/Stream중급부수효과functional-core불변분리

핵심 설명

I/O 등의 부수 효과를 순수 로직과 분리하는 전략을 배웁니다.

Java code

import java.util.*;
import java.util.function.*;

public class SideEffectManagement {
    record LogEntry(String level, String message) {}

    // 1. 부수 효과를 경계로 밀어내기
    // 순수 로직: 검증
    static List<String> validate(List<String> inputs) {
        return inputs.stream()
            .filter(s -> s != null && !s.isBlank())
            .map(String::trim)
            .filter(s -> s.length() >= 3)
            .toList();
    }

    // 부수 효과: I/O는 가장 바깥에서
    static void processAndSave(List<String> inputs) {
        List<String> valid = validate(inputs); // 순수
        valid.forEach(s -> System.out.println("저장: " + s)); // 부수 효과
    }

    // 2. 효과를 데이터로 표현
    static List<LogEntry> process(List<String> items) {
        List<LogEntry> logs = new ArrayList<>();
        List<String> results = new ArrayList<>();
        for (String item : items) {
            if (item.length() > 5) {
                results.add(item);
                logs.add(new LogEntry("INFO", "처리: " + item));
            } else {
                logs.add(new LogEntry("WARN", "스킵: " + item));
            }
        }
        return logs; // 로그를 데이터로 반환 (출력은 호출자가)
    }

    public static void main(String[] args) {
        var inputs = List.of("Hi", "Hello World", "", "Java 21", "ab");
        processAndSave(inputs);

        var logs = process(List.of("short", "longer text"));
        logs.forEach(l -> System.out.printf("[%s] %s%n", l.level(), l.message()));
    }
}

학습 팁

함수형 핵심(Functional Core), 명령형 셸(Imperative Shell) 패턴으로 순수 로직과 부수 효과를 분리하면 테스트가 쉬워집니다.

주의할 점

순수 함수 내부에서 System.out.println()을 호출하면 더 이상 순수하지 않습니다. 로깅은 반환값으로 표현하거나 바깥에서 처리하세요.

자주 묻는 질문

부수 효과 관리란 무엇인가요?

I/O 등의 부수 효과를 순수 로직과 분리하는 전략을 배웁니다.

부수 효과 관리 학습 시 주의할 점은 무엇인가요?

순수 함수 내부에서 System.out.println() 을 호출하면 더 이상 순수하지 않습니다. 로깅은 반환값으로 표현하거나 바깥에서 처리하세요.