Template Pattern in Message Distribution Systems

The Template Pattern adheres to the Open-Closed Principle and is widely implemented using hook methods. Some hooks remain static in their behavior, while others alter the execution flow. This pattern is extensively utilized in framework development. In our messaging architecture, we define required operations through a DistributionChannel interface. The BaseChannel class implements core functionality, allowing specific channel implementations to focus solely on providing their descriptive metadata.
DistributionChannel package com.messaging.core.service.distribution; import com.messaging.core.service.distribution.dto.ProcessingResults; import com.messaging.core.service.distribution.enums.ChannelType; /** * Interface defining the contract for all distribution channels * * Messages are published to specific channels, with subscribers listening to these channels */ public interface DistributionChannel { /** * Retrieves the channel type identifier * * @return {@link ChannelType} */ ChannelType getChannelType(); /** * Adds a subscriber to this channel * * @param subscriber the subscriber to add */ void addSubscriber(MessageSubscriber subscriber); /** * Removes a subscriber from this channel * * @param subscriber the subscriber to remove */ void removeSubscriber(MessageSubscriber subscriber); }
BaseChannel package com.messaging.core.service.distribution.channels; import com.messaging.core.service.distribution.DistributionChannel; import com.messaging.core.service.distribution.MessageSubscriber; import com.messaging.core.service.distribution.dto.ProcessResult; import com.messaging.core.service.distribution.dto.ProcessingResults; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; /** * Abstract base implementation of the DistributionChannel */ @Slf4j public abstract class BaseChannel implements DistributionChannel { private ArrayList> subscribers = new ArrayList<>(); /** * Adds a subscriber to this channel * * @param subscriber the subscriber to add */ @Override public void addSubscriber(MessageSubscriber subscriber) { if (!subscribers.contains(subscriber)) { subscribers.add(subscriber); } } /** * Removes a subscriber from this channel * * @param subscriber the subscriber to remove */ @Override public void removeSubscriber(MessageSubscriber subscriber) { subscribers.remove(subscriber); } /** * Processes an incoming message through all subscribers * * @param message the message to process * @param results container for processing results */ public void processMessage(K message, P results) { log.info("Message processing started..."); for (MessageSubscriber subscriber : subscribers) { subscriber.handleMessage(message, results); ProcessResult subscriberResult = results.getResult(subscriber); if (!subscriberResult.isSuccessful()) { log.info("Processing failed for {}, executing fallback...", subscriber.getClass().getSimpleName()); subscriber.handleError(message, results); log.info("Fallback processing completed for {}.", subscriber.getClass().getSimpleName()); } } log.info("Message processing completed."); } }
OrderProcessingChannel package com.messaging.core.service.distribution.channels; import com.messaging.core.service.distribution.dto.OrderMessage; import com.messaging.core.service.distribution.dto.ProcessingResults; import com.messaging.core.service.distribution.enums.ChannelType; import org.springframework.stereotype.Component; /** * Specialized channel for order processing events */ @Component public class OrderProcessingChannel extends BaseChannel { /** * Returns the channel type identifier * * @return {@link ChannelType} */ @Override public ChannelType getChannelType() { return ChannelType.ORDER_PROCESSING; } }

Tags: Template Pattern Design Patterns Messaging System java Software Architecture

Posted on Sun, 10 May 2026 03:48:50 +0000 by fael097