BE/Java

[Java] 명령형 , 선언형 프로그래밍

baek-dev 2024. 12. 12. 19:50

문제를 해결하기 위한 사고방식에 따라 명령형선언형으로 구분할 수 있다

코드 작성 및 문제 접근 방식에서 차이를 보이며, 자바에서도 이를 활용한 다양한 프로그래밍 스타일을 구현할 수 있다

 

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