개요
사전적 정의
- 프로그래밍에서 "어떤 함수나 연산의 수행결과로 시스템의 상태가 예상치 못하게 변경되는 현상"을 말합니다
- 순수 함수 (pure function)는 같은 입력 값에 대해 항상 동일한 결과를 반환하고 사이드 이펙트를 일으키지 않습니다
- 그러나 많은 함수는 내부 상태나 외부의 시스템 상태를 변경하는 동작을 포함하며, 이런 동작이 종종 사이드 이펙트를 초래합니다
var globalVar = 0
fun addWithSideEffect(x: Int, y: Int): Int {
globalVar += x
return x + y
}
- pure function은 A라는 인자가 들어왔을떄 항상 B라는 결과를 도출
- 사이드이펙트 함수의경우 A라는 인자가 들어왔을떄, 외부에 있는 전역변수 C의 값을 변화시켜서, 항상 B라는 결과를 도출 하기 어려움
Spring MVC에서의 사이드 이펙트 예시
예시1: 데이터베이스 변경
- Spring MVC는 웹 애플리케이션을 구축하기 위한 프레임 워크 입니다
- 이러한 웹 애플리케이션은 다양한 요청과 응답, 데이터베이스 연결 및 여러 외부 시스템과의 통신등 복잡한 작업을 처리해야 하기 때문에 사이드 이펙트가 발생할 가능성이 큽니다
@RestController
@RequestMapping("/users")
class UserController(val userRepository: UserRepository) {
@PostMapping("/create")
fun createUser(@RequestBody user: User): ResponseEntity<User> {
// 데이터베이스에 유저를 저장하는 동작 (사이드 이펙트 발생)
val savedUser = userRepository.save(user)
return ResponseEntity.ok(savedUser)
}
}
- 의문점
- 근데 DB는 애초에 외부 시스템인데 어떻게 사이드이펙트를 발생시키지않고 접근할 수 있을까
- -> 결론은 불가능이다
- 최대한 pure function틱하게 바꿔줘야 하기 떄문에, DB에 접근하는 메서드를 따로 분리시키는게 최선이라고 볼 수 있다
예시2: 전역 상태 변경
- Spring의 싱글턴 빈은 애플리케이션의 생명주기 동안 하나의 인스턴스만을 가집니다
- 이러한 빈의 상태를 변경하면 다른 부분에서도 영향을 받을 수 있습니다
@Service
class CounterService {
private var counter = 0
fun increment(): Int {
// 전역 상태 변경 (사이드 이펙트 발생)
return ++counter
}
}
사이드 이펙트 예시 수정
1
var globalVar = 0
fun addWithSideEffect(x: Int, y: Int): Int {
globalVar += x
return x + y
}
fun addWithoutSideEffect(x: Int, y: Int): Int {
return x + y
}
2
- 사이드 이펙트 자체를 완전히 제거하는 것은 어렵습니다
- DB에 저장하는 동작 자체가 사이드 이펙틱하기 떄문
- 그러나 우리는 코드의 명확성을 높여 사이드 이펙트가 예상 가능하도록 만들 수 있습니다

오늘 나는 무엇을 알았는가?
- 사이드 이펙트는 프로그램에서 피할 수 없는 부분이며, 때로는 의도적으로 사용됩니다
- 그러나 예기치 않은 사이드 이펙트는 버그의 원인인 될 수 있으므로, 코드를 작성할때는 가능한 순수한 함수를 사용하고, 사이드이펙트를 최소화하자!
참조 문헌
https://shin-e-dog.tistory.com/41