September 2, 2026 · 5 min read
A practical look at applying the command pattern to real-world request processing pipelines.
I am a big fan of design patterns. When I make observations, I try and look for patterns, it's in my nature. As an first hand survivor of the original J2EE effort, I have seen where these have been succesfully applied and (mostly) misued.
Design patterns provide a shared language for complex systems. While textbooks often show simple, idealized examples, their true value shines when decoupling dense, business-critical pipelines.
In this article, we’ll look at a practical, real-world application of the Command pattern used to solve a data-reduction problem in large-scale manufacturing. In short, how to apply a approach to make a large code base focued on a specific problem/solution. This is based on an experience at a previous role.
When processing high-volume manufacturing data, there’s a constant tug-of-war between data fidelity and system performance.
In a recent beverage manufacturing platform project, we faced a unique challenge: tracking orange juice lineage for consumer labeling compliance while keeping record counts manageable for downstream analytics. Here is how we used object-oriented design patterns to solve a complex data-reduction problem cleanly and maintainably.
Both are behavioral design patterns, but they solve entirely distinct architectural problems.
I will attempt to digest theory into practical application here, bear with me,
When processing high-volume manufacturing data, there’s a constant tug-of-war between data fidelity and system performance.
In a recent beverage manufacturing platform project, we faced a unique challenge: tracking orange juice lineage for consumer labeling compliance while keeping record counts manageable for downstream analytics. Here is how we used object-oriented design patterns to solve a complex data-reduction problem cleanly and maintainably.
When collecting juice at an industrial scale, every batch carries rich metadata used to back up label claims like "100% Organic, Central Florida, ABC County, Valencia Orange Juice".
| Granularity | Example Label Claim | Data Fidelity |
|---|---|---|
| High (Ideal) | 100% Central Florida, ABC County, Organic | Highest |
| Medium | 100% Florida Orange Juice | Medium |
| Low (Fallback) | Orange Juice | Baseline |
However, as batches mix, tracking every individual micro-lot creates a combinatorial explosion—often exceeding 600+ records per batch. Downstream systems and label-printing APIs could not handle this level of granularity.
We needed a system to progressively combine and generalize records in the least destructive manner possible until the total record count dropped below a configurable threshold (e.g., maximum 50 records).
To minimize impact on data fidelity, we couldn't just sweep through and merge everything aggressively. We needed to apply rules incrementally by percentage significance threshold, stepping up in tiny increments (e.g., 0.000001%).
double threshold = 0.000001;
while (records.size() > MAX_RECORDS) {
for (ReductionRule rule : reductionRules) {
records = rule.apply(records, threshold);
if (records.size() <= MAX_RECORDS) break;
}
threshold += 0.000001;
}
Because each rule contained complex grouping logic (e.g., combining by varietal vs. combining by location), putting all this logic into a single monolithic loop or within the ProductRecord class itself was out of the question.
We separated the data structures from the reduction algorithms using standard design patterns.
Each consolidation rule implements a common interface. This allows us to reorder, add, or test rules independently without touching the core execution loop.
public record ProductRecord(
BigDecimal percent,
String varietal,
String location,
BigDecimal sugarCount,
boolean organic
) {}
public interface ReductionRule {
List<ProductRecord> apply(List<ProductRecord> records, BigDecimal targetPct);
}Each reduction step needs to be a reversible, loggable unit of work — compliance audits need to see exactly which consolidation actions were applied to a batch, and a step that overshoots the target record count needs to be safely rolled back. We wrap each action in a Command, invoked and tracked by an Invoker that keeps a history for undo.
// The Command interface
public interface ReductionCommand {
void execute();
void undo();
List<ProductRecord> getResult();
}
// Concrete Command that merges records by Location below a threshold
public class MergeByLocationCommand implements ReductionCommand {
private final List<ProductRecord> records;
private final BigDecimal targetPct;
private List<ProductRecord> before;
private List<ProductRecord> after;
public MergeByLocationCommand(List<ProductRecord> records, BigDecimal targetPct) {
this.records = records;
this.targetPct = targetPct;
}
@Override
public void execute() {
before = new ArrayList<>(records);
Map<String, ProductRecord> grouped = new HashMap<>();
for (ProductRecord record : records) {
if (record.percent().compareTo(targetPct) <= 0) {
// Merge logic based on location generalization
grouped.merge(record.location(), record, this::mergeRecords);
} else {
// Keep record intact
grouped.put(UUID.randomUUID().toString(), record);
}
}
after = new ArrayList<>(grouped.values());
}
@Override
public void undo() {
// Restores the pre-execute snapshot when a step overshoots the target
after = before;
}
@Override
public List<ProductRecord> getResult() {
return after;
}
private ProductRecord mergeRecords(ProductRecord r1, ProductRecord r2) {
return new ProductRecord(
r1.percent().add(r2.percent()),
r1.varietal().equals(r2.varietal()) ? r1.varietal() : "Mixed Varietal",
r1.location(), // Preserved
r1.sugarCount().add(r2.sugarCount()).divide(BigDecimal.valueOf(2)),
r1.organic() && r2.organic() // Lose organic status if either is non-organic
);
}
}
With the patterns in place, the orchestrator loop becomes clean, testable, and robust:
public class RecordReducerOrchestrator {
private final List<ReductionRule> rules;
private final int maxThreshold;
public RecordReducerOrchestrator(List<ReductionRule> rules, int maxThreshold) {
this.rules = rules;
this.maxThreshold = maxThreshold;
}
public List<ProductRecord> reduce(List<ProductRecord> inputRecords) {
List<ProductRecord> currentRecords = new ArrayList<>(inputRecords);
BigDecimal targetPct = new BigDecimal("0.000001");
BigDecimal step = new BigDecimal("0.000001");
while (currentRecords.size() > maxThreshold && targetPct.compareTo(BigDecimal.valueOf(100)) <= 0) {
for (ReductionRule rule : rules) {
currentRecords = rule.apply(currentRecords, targetPct);
if (currentRecords.size() <= maxThreshold) {
return currentRecords;
}
}
targetPct = targetPct.add(step);
}
return currentRecords;
}
}