컴퓨터 사이언스/소프트웨어 아키텍처

[파이프-필터 아키텍처] 데이터 흐름을 분리하고 모듈화하는 방법

Dachaes 2025. 4. 28. 14:58

파이프-필터 아키텍처 

소프트웨어를 설계할 때, 복잡한 데이터를 여러 단계에 걸쳐 변환하거나 가공해야 하는 경우가 많습니다. 이런 경우 "파이프-필터(Pipe and Filter)" 아키텍처 패턴은 매우 유용하게 활용됩니다.

파이프-필터 아키텍처는 데이터를 처리하는 여러 필터(Filter)들이 파이프(Pipe)로 연결되어, 데이터를 흐름처럼 전달하고 가공하는 구조를 의미합니다. 각각의 필터는 독립적으로 동작하며, 입력을 받아 처리한 후 결과를 다음 필터에 전달합니다.

 


1.  파이프-필터 아키텍처란?

  • 필터(Filter) : 입력 데이터를 받아 가공한 후 출력하는 독립적인 컴포넌트입니다. 필터는 다른 필터에 의존하지 않고 동작해야 합니다.
  • 파이프(Pipe) : 한 필터의 출력과 다음 필터의 입력을 연결하는 통로입니다. 데이터 흐름을 담당합니다.

구조 다이어그램

Input --> [Filter A] --> [Filter B] --> [Filter C] --> Output
  • 이처럼 데이터는 한 방향으로 흐르고, 각 필터는 특정 작업만 담당하여 전체 처리 과정을 단순화합니다.

언제 사용할까?

  • 복잡한 처리를 여러 단계로 나눌 수 있을 때
  • 각 단계가 독립적이고 재사용 가능해야 할 때
  • 유연하게 파이프라인을 구성하고 싶은 경우

단, 데이터 양이 많을 경우 필터 간 통신 비용이 무시할 수 없으므로 성능에 주의가 필요합니다.

 


2.  파이프-필터 패턴의 특징

  • 모듈화(Modularity) : 각 필터는 독립적으로 개발 및 테스트할 수 있습니다.
  • 재사용성(Reusability) : 필터는 다른 프로젝트나 파이프라인에서도 재사용할 수 있습니다.
  • 유연성(Flexibility) : 필터의 추가/제거/교체가 비교적 용이합니다.
  • 성능 문제(Performance) : 중간 데이터 저장과 전송이 필요하므로 오버헤드가 발생할 수 있습니다.

 


3.  파이프-필터 아키텍처 예제

간단한 문자열 처리 예제를 통해 파이프-필터 구조를 살펴봅시다.

class Filter:
    def process(self, data):
        raise NotImplementedError

class LowercaseFilter(Filter):
    def process(self, data):
        return data.lower()

class RemovePunctuationFilter(Filter):
    def process(self, data):
        import string
        return data.translate(str.maketrans('', '', string.punctuation))

class SplitWordsFilter(Filter):
    def process(self, data):
        return data.split()

class Pipeline:
    def __init__(self):
        self.filters = []
    
    def add_filter(self, filter):
        self.filters.append(filter)
    
    def run(self, data):
        for filter in self.filters:
            data = filter.process(data)
        return data

# 파이프라인 구성
pipeline = Pipeline()
pipeline.add_filter(LowercaseFilter())
pipeline.add_filter(RemovePunctuationFilter())
pipeline.add_filter(SplitWordsFilter())

# 실행
input_data = "Hello, World! This is Pipe-Filter architecture."
output_data = pipeline.run(input_data)
print(output_data)

실행 결과 :

['hello', 'world', 'this', 'is', 'pipefilter', 'architecture']
  • 여기서 각각의 Filter 클래스가 독립적인 필터 역할을 하고, Pipeline 클래스는 이들을 순서대로 연결하는 파이프 역할을 수행합니다.

 


4.  파이프-필터 패턴의 활용 사례

  • 컴파일러 설계 : 소스 코드 → 어휘 분석 → 구문 분석 → 의미 분석 → 코드 생성
  • 데이터 처리 파이프라인 : ETL(Extract, Transform, Load) 시스템
  • 멀티미디어 스트리밍 : 오디오, 비디오 데이터의 실시간 변환 및 처리
  • 유닉스/Linux 시스템 : cat, grep, sort 등의 명령어 파이프 연결 (|)

 


5.  마무리 

파이프-필터 아키텍처는 데이터 처리 과정을 명확하게 분리하고, 각 단계를 독립적으로 관리할 수 있게 해주는 설계 패턴입니다. 특히 복잡한 변환이나 가공이 필요한 시스템에서 구조를 단순화하고 유연성을 높이는 데 큰 도움이 됩니다. 다만 데이터 양이 많거나 실시간 처리가 필요한 경우에는 성능 고려가 반드시 필요합니다. 상황에 맞게 적절히 활용하면 훨씬 깔끔하고 유지보수하기 쉬운 소프트웨어를 만들 수 있습니다.

함께 보면 좋은 자료

외부 사이트 :