문제를 해결하기 위한 사고방식에 따라 명령형과 선언형으로 구분할 수 있다
코드 작성 및 문제 접근 방식에서 차이를 보이며, 자바에서도 이를 활용한 다양한 프로그래밍 스타일을 구현할 수 있다
1. 명령형 프로그래밍
특징
- 어떻게(HOW) 문제를 해결할지 구체적으로 지시
- 상태와 명령어를 중심으로 동작
- 로직을 단계적으로 작성하며, 제어 구조(반복문, 조건문 등)를 사용하여 수행 과정을 정의
특징적 요소
- 변수 : 상태를 저장
- 루프 : 반복작업수행
- 조건문 : 논리 흐름 제어
- 명령과 제어의 연속으로 문제를 해결함
장점
- 알고리즘 구현과 제어 흐름을 명확히 이해할 수 있음
- 저수준 작업(메모리 관리, 상태 관리)에 적합
단점
- 코드가 길어지고 복잡해질 수 있음
- 병렬 처리 및 함수 추상화가 어렵거나 번거로움
예제
리스트에서 짝수만 필터링하여 합산
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);
List<Integer> evenNumbers = new ArrayList<>();
int sum = 0;
for (int number : numbers) {
if (number % 2 == 0) { // 짝수 체크
evenNumbers.add(number);
sum += number;
}
}
System.out.println("짝수 목록: " + evenNumbers);
System.out.println("짝수 합: " + sum);
}
}
2. 선언형 프로그래밍
특징
- 무엇(What)을 해야하는지 선언적으로 표현
- 작업의 목적을 정의, 구체적인 실행방법은 숨김
- 상태변화를 최소화, 불변성을 중시
특징적 요소
- 함수형 프로그래밍 패러다임에 적합
- 제어프름이 아닌 선언적 데이터 처리를 강조
- 스트림 및 람다식으로 쉽게 구현 가능
장점
- 간결하고 가독성 높은 코드 작성 가능
- 병렬처리 및 최적화에 적합
- 상태 변화 관리가 쉬움
단점
- 저수준 제어가 필요한 경우에는 부적합
- 초보자에게 익숙해지기 어려울수 있음
예제
같은 문제를 스트림으로 해결
import java.util.List;
public class DeclarativeExample {
public static void main(String[] args) {
List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6);
int sum = numbers.stream()
.filter(number -> number % 2 == 0) // 짝수 필터링
.mapToInt(Integer::intValue) // int 변환
.sum(); // 합산
System.out.println("짝수 합: " + sum);
}
}
3. 명령형 vs 선언형 비교
특징 | 명령형 | 선언형 |
접근 방식 | 어떻게(how) 문제를 해결할지 명시 | 무엇(what)을 해야하는지 명시 |
코드 스타일 | 절차적, 단계적 | 표현식 기반, 간결 |
상태 관리 | 상태 변화 존재 | 불변성을 중시 |
사용 사례 | 복잡한 알고리즘, 상태관리가 중요한경우 | 데이터변환, 병렬처리, 함수형 프로그래밍 |
가독성 | 복잡한 로직에서 난해할수 있음 | 의도가 명확하여 가독성이 높음 |
병렬 처리 | 어렵고 복잡함 | 내장된 병렬 처리 지원(스트림) |
4. 자바에서의 구현 사례
명령형의 주요 기술
- 루프 (`for`, `while`)
- 조건문 (`if-else`)
- 명령어(`break`,`continue`)
선언형의 주요 기술
- stream api : 데이터 처리 파이프라인
- 람다식 : 함수형 스타일 코드 작성
- Optional : null 안정성과 선언적 처리를 제공
- 불변 객체 : 상태 변화를 줄이기 위한 설계
5. 두 패러다임의 조화
바에서는 명령형과 선언형을 혼합하여 사용하는 경우가 많다
예를 들어, 비즈니스 로직의 주요 알고리즘은 명령형으로 작성하고, 데이터 처리 부분은 선언형으로 작성하는 방식이 효과적이다
예제
파일 내 특정 단어를 필터링 후 결과 저장
import java.io.*;
import java.util.*;
import java.util.stream.*;
public class MixedExample {
public static void main(String[] args) throws IOException {
// 명령형 방식으로 파일 읽기
List<String> lines = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new FileReader("input.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
lines.add(line);
}
}
// 선언형 방식으로 특정 단어 필터링
List<String> filteredLines = lines.stream()
.filter(line -> line.contains("keyword"))
.collect(Collectors.toList());
// 명령형 방식으로 결과 저장
try (BufferedWriter writer = new BufferedWriter(new FileWriter("output.txt"))) {
for (String line : filteredLines) {
writer.write(line);
writer.newLine();
}
}
}
}
요약
- 명령형 프로그래밍은 세부적으로 제어가 필요한 로직에서 유리합니다.
- 선언형 프로그래밍은 간결성과 병렬 처리가 필요한 데이터 처리 작업에 적합합니다.
- 자바는 두 스타일을 모두 지원하며, 상황에 맞게 조화를 이루어 사용할 수 있습니다.
'BE > Java' 카테고리의 다른 글
[Java] 영속성 (0) | 2024.12.16 |
---|---|
[Java] 레이어드 아키텍처와 mvc (1) | 2024.12.15 |
[Java] 어노테이션 (1) | 2024.12.11 |
[Java] JDBC와 JPA (0) | 2024.12.11 |
[Java] 람다식 (0) | 2024.12.10 |