2025. 3. 19. 02:11ㆍProject Reactor
자바에서의 명령형 프로그래밍과 선언형 프로그래밍
소프트웨어 개발에서 명령형 프로그래밍(Imperative Programming)과 선언형 프로그래밍(Declarative Programming)은 코드를 작성하는 두 가지 주요 패러다임입니다. 자바(Java)에서도 이 두 가지 패러다임을 모두 활용할 수 있으며, 각각의 방식이 가지는 특성과 차이점을 이해하는 것이 중요합니다.
1. 명령형 프로그래밍(Imperative Programming)
📌 개념
명령형 프로그래밍은 컴퓨터가 무엇을 어떻게 해야 하는지를 명시적으로 기술하는 방식입니다. 즉, "어떻게(How)" 문제를 해결할 것인지 절차적으로 지시하는 방식이 특징입니다.
이 방식은 개발자가 프로그램의 실행 흐름을 직접 제어하며, 변수 할당, 루프, 조건문 등을 사용하여 데이터를 처리합니다.
🔹 특징
- 절차적(Procedural) 접근: 코드가 실행될 순서를 단계적으로 명시함
- 상태 변화(State Change) 기반: 변수 값을 변경하며 연산 수행
- 명확한 제어 흐름(Control Flow) 필요: 반복문(
for
,while
), 조건문(if-else
)을 사용
🔸 예제: 리스트의 짝수 요소를 필터링한 후 제곱하기
import java.util.ArrayList;
import java.util.List;
public class ImperativeExample {
public static void main(String[] args) {
List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> squaredEvens = new ArrayList<>();
for (Integer num : numbers) {
if (num % 2 == 0) { // 짝수인지 확인
squaredEvens.add(num * num); // 제곱하여 리스트에 추가
}
}
System.out.println(squaredEvens); // [4, 16, 36, 64, 100]
}
}
✅ 설명
for
루프를 사용하여 리스트를 반복하면서 짝수를 찾음- 조건문(
if
)을 사용하여 필터링 수행 - 새로운 리스트(
squaredEvens
)에 추가하여 최종 결과를 생성
이 방식은 명확한 실행 순서가 있으며, 데이터가 반복문과 조건문을 거치면서 변환됩니다.
2. 선언형 프로그래밍(Declarative Programming)
📌 개념
선언형 프로그래밍은 "무엇(What)"을 해야 하는지에 초점을 맞추는 방식입니다. 실행 순서(How)를 명시적으로 정의하는 대신, 데이터 변환의 목적과 결과에 집중합니다.
이 방식에서는 불변성(Immutable Data)과 함수형 프로그래밍(Function Composition) 개념이 강조됩니다.
🔹 특징
- 목적 지향적(Objective-Oriented): "어떻게"보다는 "무엇을" 해야 하는지 기술
- 불변성(Immutability): 기존 데이터를 변경하지 않고 새 데이터 반환
- 함수형 프로그래밍 스타일:
Stream API
,map
,filter
,collect
등의 활용
🔸 예제: 스트림을 활용한 짝수 필터링 및 제곱 연산
import java.util.List;
import java.util.stream.Collectors;
public class DeclarativeExample {
public static void main(String[] args) {
List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> squaredEvens = numbers.stream()
.filter(num -> num % 2 == 0) // 짝수 필터링
.map(num -> num * num) // 제곱 연산
.collect(Collectors.toList()); // 리스트로 수집
System.out.println(squaredEvens); // [4, 16, 36, 64, 100]
}
}
✅ 설명
stream()
을 사용하여 데이터를 선언적 방식으로 변환filter()
를 활용하여 짝수만 남김map()
을 사용하여 값을 변환(제곱 연산)collect()
를 이용해 최종 리스트로 변환
루프와 상태 변경 없이 원하는 작업을 간결하게 표현할 수 있습니다.
3. 명령형 vs 선언형 프로그래밍 비교
구분 | 명령형 프로그래밍 | 선언형 프로그래밍 |
---|---|---|
접근 방식 | 어떻게(How) 처리할지 명시 | 무엇(What)을 해야 하는지 기술 |
코드 스타일 | 절차적(Procedural), 단계별 접근 | 선언적(Declarative), 조합적 접근 |
상태 관리 | 변경 가능한 변수 사용 (Mutable) | 불변성(Immutability) 강조 |
제어 흐름 | 명시적 (for , while , if 사용) |
Stream API , filter , map 활용 |
가독성 | 코드가 길어질 수 있음 | 간결하고 직관적 |
함수형 프로그래밍 | 거의 사용되지 않음 | 함수형 스타일 적극 활용 |
4. 언제 명령형과 선언형을 사용할까?
✅ 명령형 프로그래밍이 적합한 경우
- 코드가 매우 단순하고 작은 경우
- 특정 순서를 따라야 하는 경우 (예: 파일 읽기, I/O 연산)
- 성능이 중요한 저수준 로직(예: 루프 최적화, 직접 메모리 관리)
✅ 선언형 프로그래밍이 적합한 경우
- 데이터 변환이나 집계 작업이 많은 경우 (예: 컬렉션 조작)
- 코드 가독성을 높이고 유지보수를 쉽게 하고 싶은 경우
- 병렬 스트림(Parallel Streams) 등을 활용할 경우
5. 결론
자바에서는 명령형과 선언형 프로그래밍을 모두 활용할 수 있으며, 각각의 장점과 단점이 존재합니다.
- 명령형 프로그래밍은 절차적 제어가 필요한 곳에서 유용하지만, 코드가 길어지고 가독성이 떨어질 수 있습니다.
- 선언형 프로그래밍은 스트림(Stream API), 람다 표현식(Lambda Expressions)을 통해 간결하고 유지보수하기 좋은 코드를 작성할 수 있습니다.
현대 자바에서는 선언형 프로그래밍 방식이 선호되는 추세이며, 특히 함수형 프로그래밍 개념을 적극 활용하는 것이 더 효율적인 경우가 많습니다.
🔥 결론: 명령형과 선언형의 장점을 적절히 조합하여 최적의 코드 스타일을 선택하는 것이 중요합니다. 🚀
'Project Reactor' 카테고리의 다른 글
Non-Reactive(비반응적) vs. Reactive(반응적): 우유 공장 예제 (0) | 2024.11.21 |
---|---|
How to read marble diagrams? (0) | 2024.11.20 |
Reactive Streams (0) | 2024.11.17 |