함수형 프로그래밍의 장점과 실전 활용

2025. 2. 28. 18:27개발/JavaScript

반응형

함수형 함수형 하는데 너무 어렵더라고요 

분명 중요하고 아는 내용인데 개발을 하면서 많이 놓지고 있는 부분이었서요 

 

하지만 최근에 저는 함수형 프로그래밍에 대한 이해를 높이고,(배우고~)

JavaScript에서 그것을 활용하여 코드를 개선하는 데 주력했습니다.

오늘은 제가 느낀 점과 함께, 함수형 프로그래밍이 어떻게 복잡한 코드를

더 간결하게 만들어주는지에 대해 이야기하고 싶습니다.

 

아직 100% 이해를 하고 적립한 것이 아닌 아~~ 정도 60% 이해를 한 상황이라 설명이 많이 미숙합니다

 

단도직입적으로 

기존 코드의 문제점

제가 처음 접했던 코드는 다음과 같은 형태로,

길고 복잡해서 유지보수하기 어려운 부분이 많았습니다:

for (let i = start; i < end; i++) {
    const element = KEYWORD_ARRAY[i];
    if (!element) {
        break;
    }
    if (element.relKeyword === keyword) {
        KEYWORD_ARRAY[i].category1 = keyword_info.category ? keyword_info.category.category1 : "";
        KEYWORD_ARRAY[i].category2 = keyword_info.category ? keyword_info.category.category2 : "";
        KEYWORD_ARRAY[i].category3 = keyword_info.category ? keyword_info.category.category3 : "";
        KEYWORD_ARRAY[i].category4 = keyword_info.category ? keyword_info.category.category4 : "";
        KEYWORD_ARRAY[i].total = keyword_info.total;
    }
}

BASE_KEYWORD_ARRAY.forEach((element, index) => {
    if (!element) return;
    if (element.relKeyword === keyword) {
        BASE_KEYWORD_ARRAY[index].category1 = keyword_info.category ? keyword_info.category.category1 : "";
        BASE_KEYWORD_ARRAY[index].category2 = keyword_info.category ? keyword_info.category.category2 : "";
        BASE_KEYWORD_ARRAY[index].category3 = keyword_info.category ? keyword_info.category.category3 : "";
        BASE_KEYWORD_ARRAY[index].category4 = keyword_info.category ? keyword_info.category.category4 : "";
        BASE_KEYWORD_ARRAY[index].total = keyword_info.total;
    }
});

이런 복잡한 로직을 함수형으로 바꾸면 어떻게 될까요?

함수형 접근의 장점

함수형 프로그래밍의 장점은 코드를 더 명확하고 간결하게 만들 수 있다는 점입니다.

다음과 같이 코드를 리팩토링할 수 있었습니다:

export function* map(iterable, mapFunction) {
    let index = 0;
    for (const item of iterable) {
        yield mapFunction(item,index++);
    }
}

// Generator function that filters elements of an iterable based on a filter function
export function* filter(iterable, filterFunction) {
    for (const item of iterable) {
        if (filterFunction(item)) {
            yield item;
        }
    }
}
export function* sort(iterable, compareFunction) {
    const sortedArray = Array.from(iterable).sort(compareFunction);
    for (const item of sortedArray) {
        yield item;
    }
}

export function* slice(iterable, start, end) {
    let index = 0;
    for (const item of iterable) {
        if (index >= start && index < end) {
            yield item;
        }
        index++;
        if (index >= end) {
            break;
        }
    }
}

export function* reverse(iterable) {
    const items = Array.from(iterable);
    for (let i = items.length - 1; i >= 0; i--) {
        yield items[i];
    }
}
export function* batch(iterable, size) {
    let batch = [];
    for (const item of iterable) {
        batch.push(item);
        if (batch.length === size) {
            yield batch;
            batch = [];
        }
    }
    if (batch.length > 0) {
        yield batch;
    }
}

 

클래스로 보기 편하게 수정을 하더라고요

export class Processor {
    constructor(iterable) {
        this.iterable = iterable;
    }

    map(mapFunction) {
        this.iterable = map(this.iterable, mapFunction);
        return this;
    }

    filter(filterFunction) {
        this.iterable = filter(this.iterable, filterFunction);
        return this;
    }

    sort(compareFunction) {
        this.iterable = sort(this.iterable, compareFunction);
        return this;
    }
    slice(start, end) {
        this.iterable = slice(this.iterable, start, end);
        return this;
    }

    reverse() {
        this.iterable = reverse(this.iterable);
        return this;
    }
    batch(size) {
        this.iterable = batch(this.iterable, size);
        return this;
    }
    toArray() {
        return Array.from(this.iterable);
    }
}

 

// 키워드 정보를 업데이트하는 함수
function updateKeywordInfo(array, keyword, keywordInfo) {
    return array.map(element => {
        if (element && element.relKeyword === keyword) {
            return {
                ...element,
                category1: keywordInfo.category ? keywordInfo.category.category1 : "",
                category2: keywordInfo.category ? keywordInfo.category.category2 : "",
                category3: keywordInfo.category ? keywordInfo.category.category3 : "",
                category4: keywordInfo.category ? keywordInfo.category.category4 : "",
                total: keywordInfo.total,
            };
        }
        return element; // 업데이트가 필요 없는 경우 원래 요소 반환
    });
 });

 

// 사용하는 방법
const updatedArray = updateKeywordInfo(KEYWORD_ARRAY, keyword, keyword_info);
const updatedBaseArray = updateKeywordInfo(BASE_KEYWORD_ARRAY, keyword, keyword_info);

 

이로 인해 코드가 훨씬 더 읽기 쉽게 되었고,

특정 롤백 없이도 쉽게 테스트할 수 있도록 했습니다.

 

느낀 점

함수형 프로그래밍이 아직 익숙하지 않아서, 처음에 함수형으로 만드는 데 시간이 걸렸습니다.

응용할 때도 미숙한 점이 많았지만,

실제로 사용하고 테스트하는 과정에서 오류가 덜 발생해 긍정적인 경험을 했습니다.

React와 TypeScript로 관련된 내용을 들었을 때,

일반 JavaScript에서 사용할 수 있을지 걱정했지만, 직접 만들어보니 생각보다 쉽고 편했습니다.

 

그럼에도 불구하고, 아직 제가 함수형으로 한 번에 만들어볼 만한 내용에 대해 더 연습이 필요하다고 느끼고 있습니다.

앞으로 더 많은 연습을 통해 함수형 프로그래밍의 매력을 더욱 깊이 이해해보고 싶습니다.

결론

함수형 프로그래밍은 복잡한 로직을 간결하게 만들고,

코드의 가독성과 재사용성을 높이는 강력한 도구입니다.

제가 처음 접한 이 개념이 익숙해지고, 더 많은 기능을 구현할 수 있게 될 날을 기대합니다.

앞으로도 계속해서 함수형 프로그래밍을 활용하여 보다 나은 코드를 작성해 나가고자 합니다.

 

PS 분명 더 짧다고 했는데? 라고 생각을 하시지만 함수형을 만드는 부분을 적은 것이다 보니 더 길게 보이겠지만 

장기적으로 저 함수들을 활용한다고 하면 코드들은 분명 더 개선이 될 것입니다.

반응형