자바에서 "사이드 임팩트(Side Effect)"란, 함수나 메서드가 호출될 때, 외부 상태(즉, 함수나 메서드의 입력이나 반환 값이 아닌 상태)에 영향을 미치는 것을 의미합니다. 이는 예측하지 못한 결과를 초래할 수 있기 때문에, 특히 함수형 프로그래밍에서는 피하고자 하는 경향이 있습니다.

사이드 임팩트의 예

1. 변수의 변경

메서드가 호출될 때, 클래스의 인스턴스 변수(필드)의 값을 변경하는 경우가 사이드 임팩트의 전형적인 예입니다.

java코드 복사
public class Counter {
    private int count = 0;

    public void increment() {
        count++;  // count 필드의 값을 변경
    }

    public int getCount() {
        return count;
    }
}

위 코드에서 increment() 메서드는 count라는 외부 상태(인스턴스 변수)를 변경합니다. 이 메서드 호출의 사이드 임팩트는 count 값이 변경된다는 것입니다.

2. 전역 상태의 변경

전역 변수나 싱글톤 객체의 상태를 변경하는 것도 사이드 임팩트를 발생시킬 수 있습니다.

java코드 복사
public class GlobalCounter {
    public static int count = 0;

    public static void increment() {
        count++;  // 전역 변수 count의 값을 변경
    }
}

여기서 increment() 메서드는 전역 상태를 변경합니다. 이 전역 변수의 변경은 프로그램의 다른 부분에 영향을 미칠 수 있습니다.

3. 입력 인자의 변경 (Mutating Arguments)

메서드가 전달받은 인자의 값을 변경하는 것도 사이드 임팩트입니다.

java코드 복사
public class Example {
    public void modifyArray(int[] arr) {
        arr[0] = 10;  // 전달된 배열의 첫 번째 요소를 변경
    }
}

public class Main {
    public static void main(String[] args) {
        int[] numbers = {1, 2, 3};
        Example example = new Example();
        example.modifyArray(numbers);

        System.out.println(numbers[0]);  // 출력 결과: 10
    }
}

위 코드에서 modifyArray() 메서드는 전달된 배열의 첫 번째 요소를 변경합니다. 이로 인해 메서드 호출 이후 배열의 상태가 변경되었으며, 이는 원래 호출 코드에 예상치 못한 영향을 줄 수 있습니다.

사이드 임팩트를 피하는 방법

함수형 프로그래밍에서는 사이드 임팩트를 피하기 위해 불변 객체를 사용하거나, 입력값을 변경하지 않고 새 값을 반환하는 방식을 선호합니다.

java코드 복사
public class PureFunctionExample {
    public int add(int a, int b) {
        return a + b;  // 외부 상태를 변경하지 않고 새 값을 반환
    }
}

이 예제에서 add() 메서드는 입력값 ab를 변경하지 않으며, 외부 상태에 영향을 미치지 않고 단순히 합을 반환합니다. 이는 사이드 임팩트가 없는 "순수 함수(Pure Function)"의 예입니다.

사이드 임팩트와 소프트웨어 설계

사이드 임팩트를 적절하게 관리하면 코드의 예측 가능성과 유지보수성을 높일 수 있습니다. 그러나 사이드 임팩트를 완전히 피할 수는 없습니다. 예를 들어, 데이터베이스에 저장하거나 파일에 쓰는 작업은 본질적으로 사이드 임팩트를 수반합니다. 중요한 것은 이와 같은 작업을 명확하게 식별하고, 적절하게 제어하는 것입니다.