Mastering the Pipes and Filters Architecture

Krzysztof Słomka
5 min readMar 13, 2023

--

The Pipes and Filters architecture is a well-known design pattern in software engineering that involves breaking down a system into a series of independent components, or filters, that communicate with each other through pipes. Each filter performs a specific task on the data that flows through the pipeline, and the output of one filter becomes the input of the next filter. This architecture is highly modular and flexible and allows for easy reusability and scalability of components. In this blog post, we will explore the Pipes and Filters architecture in depth, its cons, and its pros.

What is Pipes & Filters architecture?

Pipes & Filters architecture is a pattern that involves breaking down a system into a series of independent processing steps. Each step is called a filter, and the data is passed between the filters through a pipe. Filters can be combined in different ways to create a variety of processing pipelines.

The Pipes & Filters architecture is particularly well-suited for data processing systems, where data is received, transformed, and sent to other systems or processes. The architecture allows for the separation of concerns, which makes the system more modular and easier to maintain. It also allows for the reusability of filters in different processing pipelines.

Components of Pipes & Filters architecture

There are three main components of the Pipes & Filters architecture.

Pipes

Pipes are channels through which data flows between filters. In a data processing system, the data is usually passed between filters in the form of messages. Pipes can be implemented using techniques such as shared memory, sockets, or message queues.

Filters

Filters are processing steps that receive data from one or more pipes, perform some processing, and send the processed data to one or more pipes. Filters are independent of each other and can be combined in different ways to create a variety of processing pipelines.

Filters can be classified into three categories:

  • Source Filters: receive input data from an external system or source and pass it to the next filter in the pipeline.
  • Processing Filters: receive input data from one or more pipes, perform some processing on the data, and send the processed data to one or more pipes.
  • Sink Filters: receive data from the previous filter in the pipeline, process it, and send it to an external system or sink.

Pump

A pump is responsible for controlling the flow of data through the system. It reads data from an external source and sends it to the first filter in the pipeline. Similarly, it receives data from the last filter in the pipeline and sends it to an external sink.

Advantages of Pipes & Filters architecture:

The Pipes & Filters architecture has several advantages, including:

  1. Separation of concerns
    The architecture allows for the separation of concerns between different processing steps. Each filter is responsible for a specific task, which makes the system more modular and easier to maintain.
  2. Reusability
    Filters can be reused in different processing pipelines, which reduces the development time and improves the overall system performance.
  3. Scalability
    The architecture allows for easy scalability of the system. Additional filters can be added to the pipeline to handle increased processing requirements.
  4. Fault tolerance
    The architecture provides fault tolerance by isolating the filters from each other. If one filter fails, it does not affect the other filters in the pipeline.
  5. Testing
    The architecture makes it easier to test individual filters as they can be tested in isolation.
  6. Performance
    The architecture allows for the parallel processing of data, which can significantly improve the system’s performance.

Any disadvantages?

While the Pipes & Filters architecture has many advantages, it also has some disadvantages.

One of the main drawbacks is that the architecture can become complex when dealing with large and complex data processing systems. The need to coordinate the different filters, handle errors, and ensure data consistency can make the system difficult to understand and maintain.

Additionally, the architecture may not be suitable for systems that require real-time processing, as the processing time for each filter may vary, leading to unpredictable delays in the data flow.

Finally, the Pipes & Filters architecture may not be the best choice for systems that require complex routing and processing logic, as the simple linear pipeline may not be able to handle all the necessary processing steps.

Example

Let’s consider an example of a simple data processing system that processes customer orders. The system consists of four filters: the order receiver, the order parser, the order validator, and the order writer. The order receiver receives customer orders and sends them to the order parser. The order parser parses the order data and sends it to the order validator. The order validator validates the order data and sends it to the order writer. Finally, the order writer writes the validated order data into a database.

The data flow between the filters is shown in the following diagram

Order Receiver -> Order Parser -> Order Validator -> Order Writer

The system can be implemented using the Pipes & Filters architecture, as shown below

The system can be controlled by a Pump, which reads the customer orders from an external system and sends them to the Order Receiver. Similarly, it receives the validated order data from the Order Writer and sends it to an external sink.

<?php

class Order {
public string $customerName;
public string $productName;
public int $quantity;
public float $price;
}

interface Filter {
function process(Order $input): Order;
}

final class OrderReceiver implements Filter {
function process(Order $input): Order {
echo 'Receive the order data';

return $input;
}
}

final class OrderValidator implements Filter {
function process(Order $input): Order {
echo 'Validate the order data';

return $input;
}
}

final class OrderProcessor implements Filter {
function process(Order $input): Order {
echo 'Process the order data';

return $input;
}
}

final class OrderWriter implements Filter {
function process(Order $input): Order {
echo 'Write the order data to the database';

return $input;
}
}

class Pump {
private array $filters = [];

function addFilter(Filter $filter): void {
$this->filters[] = $filter;
}

function process(Order $input): mixed {
foreach ($this->filters as $filter) {
$input = $filter->process($input);
}
return $input;
}
}

// Create the pipeline
$pipeline = new Pump();
$pipeline->addFilter(new OrderReceiver());
$pipeline->addFilter(new OrderValidator());
$pipeline->addFilter(new OrderProcessor());
$pipeline->addFilter(new OrderWriter());

// Process the data
$inputData = new Order();
$inputData->customerName = 'John Doe';
$inputData->productName = 'Product A';
$inputData->quantity = 3;
$inputData->price = 10.00;

try {
$result = $pipeline->process($inputData);
echo 'Order processed successfully';
} catch (\Throwable $e) {
// An error occurred while processing the order
}

Conclusion

The Pipes & Filters architecture is a powerful pattern that can be used to create data processing systems that are modular, scalable, and fault-tolerant. It allows for separating concerns between different processing steps, making the system easier to maintain and test. The architecture is particularly well-suited for systems that process large amounts of data, as it allows for parallel processing of data. Overall, the Pipes & Filters architecture is a valuable tool for software architects and developers who want to create high-performance, reliable data processing systems.

--

--

Krzysztof Słomka
Krzysztof Słomka

Written by Krzysztof Słomka

My name is Krzysztof, I'm a software architect and developer, with experience of leading teams and delivering large scalable projects for over 13 years...

No responses yet