800===Dev Docs and License/이론 문서

함수형 프로그래밍 vs 명령형 프로그래밍 비교 가이드 🔄

블로글러 2024. 11. 3. 22:37

함수형 프로그래밍과 기존의 명령형 프로그래밍의 차이점을 실전 예제와 함께 알아보겠습니다!

핵심 차이점 요약 🎯

구분 명령형 프로그래밍 함수형 프로그래밍
접근방식 HOW(어떻게) 중심 WHAT(무엇을) 중심
상태관리 상태 변경 가능 불변성 유지
실행순서 순서 중요 순서 덜 중요
제어흐름 반복문, 조건문 재귀, 함수 조합

실제 코드로 보는 차이점 💻

1. 배열의 합계 구하기

// 명령형 방식
function getSum(numbers) {
    let sum = 0;  // 변경 가능한 상태
    for(let i = 0; i < numbers.length; i++) {
        sum += numbers[i];  // 상태 변경
    }
    return sum;
}

// 함수형 방식
const getSum = numbers => 
    numbers.reduce((sum, num) => sum + num, 0);  // 불변성 유지

2. 사용자 필터링

// 명령형 방식
function getActiveUsers(users) {
    const result = [];
    for(let i = 0; i < users.length; i++) {
        if(users[i].active && users[i].age > 18) {
            result.push({
                name: users[i].name,
                age: users[i].age
            });
        }
    }
    return result;
}

// 함수형 방식
const getActiveUsers = users =>
    users
        .filter(user => user.active && user.age > 18)
        .map(({name, age}) => ({name, age}));

3. 데이터 변환

// 명령형 방식
function processOrders(orders) {
    const result = [];
    for(let i = 0; i < orders.length; i++) {
        if(orders[i].status === 'completed') {
            let total = 0;
            for(let j = 0; j < orders[i].items.length; j++) {
                total += orders[i].items[j].price;
            }
            if(total > 100) {
                result.push({
                    id: orders[i].id,
                    total: total
                });
            }
        }
    }
    return result;
}

// 함수형 방식
const processOrders = orders =>
    orders
        .filter(order => order.status === 'completed')
        .map(order => ({
            id: order.id,
            total: order.items.reduce((sum, item) => sum + item.price, 0)
        }))
        .filter(order => order.total > 100);

실제 사용 시나리오 비교 🎭

1. 상태 관리

// 명령형 방식 (React Class Component)
class Counter extends React.Component {
    constructor(props) {
        super(props);
        this.state = { count: 0 };
    }

    increment() {
        this.setState({ count: this.state.count + 1 });
    }

    render() {
        return <button onClick={() => this.increment()}>
            Count: {this.state.count}
        </button>;
    }
}

// 함수형 방식 (React Hooks)
const Counter = () => {
    const [count, setCount] = useState(0);
    return (
        <button onClick={() => setCount(count + 1)}>
            Count: {count}
        </button>
    );
};

2. 에러 처리

// 명령형 방식
function processData(data) {
    try {
        let result;
        if(data) {
            result = someProcess(data);
            if(result) {
                return formatResult(result);
            }
        }
        throw new Error('Invalid data');
    } catch(e) {
        return null;
    }
}

// 함수형 방식
const processData = data =>
    Option.of(data)
        .map(someProcess)
        .map(formatResult)
        .getOrElse(null);

장단점 비교 ⚖️

명령형 프로그래밍

장점 👍

  • 직관적이고 이해하기 쉬움
  • 하드웨어에 가까운 로우레벨 최적화 가능
  • 기존 개발자들에게 친숙

단점 👎

  • 코드 복잡도가 높아지면 유지보수 어려움
  • 부작용(side effects) 발생 가능성 높음
  • 병렬 처리 구현이 까다로움

함수형 프로그래밍

장점 👍

  • 코드 가독성과 재사용성 향상
  • 테스트와 디버깅이 용이
  • 병렬 처리에 적합
  • 버그 발생 가능성 감소

단점 👎

  • 학습 곡선이 가파름
  • 일부 상황에서 성능 오버헤드 발생 가능
  • 기존 라이브러리와의 호환성 문제 가능

실무 적용 팁 💡

  1. 점진적 도입
  2. // 기존 코드를 점진적으로 함수형으로 변경 const oldCode = function(data) { let result = []; // ... 기존 로직 }; // 일부분만 함수형으로 변경 const newCode = data => someOperation(data) .then(oldCode) // 기존 코드와 조합 .then(functionalOperation);
  3. 하이브리드 접근
    • 순수 함수형으로 갈 필요 없음
    • 상황에 맞게 두 패러다임 혼용

마치며 🎁

두 방식은 각각의 장단점이 있으며, 실무에서는 상황에 맞게 적절히 조합하여 사용하는 것이 현명합니다. 함수형 프로그래밍의 개념을 잘 이해하고 점진적으로 도입하면서 코드의 품질을 개선해나가는 것을 추천드립니다!


추가적인 궁금점이나 실제 적용 사례에 대해 궁금하시다면 댓글로 남겨주세요! 😊

728x90