What design patterns have you applied in your projects, such as message queues, asynchronous pools, enterprise bus, or command and query separation?
sobes.tech AI
Answer from AI
When developing high-load frontend applications and SPAs, the following design patterns were actively used:
-
CQRS (Command Query Responsibility Segregation): Separation of operations that modify state (commands) and operations that retrieve data (queries). This allows optimizing data processing for reading and writing independently, increasing performance and scalability.
-
Publisher/Subscriber (Pub/Sub): Implementation of an event system where components can subscribe to specific event types and receive notifications about them. Used for loose coupling between modules and asynchronous interaction.
-
Mediator: Using a central mediator object to coordinate interactions between different modules or components. Helps reduce direct coupling between objects.
-
Asynchronous pools (at the UI/browser level): Managing parallel asynchronous operations (e.g., API requests) with a limit on the number of tasks executed simultaneously. Although not a classic thread pool, in browsers, control over the number of asynchronous functions (e.g., promises) is implemented.
Although "message queue" or "enterprise bus" in the classic sense were not directly used on the frontend, the Pub/Sub patterns and architectural approaches close to CQRS implemented similar principles of asynchronous processing and responsibility distribution.
Example of Pub/Sub implementation:
// Simple event and subscriber storage
const events = {};
// Subscription function
const subscribe = (eventName, callback) => {
if (!events[eventName]) {
events[eventName] = [];
}
events[eventName].push(callback);
};
// Publication function
const publish = (eventName, data) => {
if (events[eventName]) {
events[eventName].forEach(callback => {
// Asynchronous call to subscriber
setTimeout(() => callback(data), 0);
});
}
};
// Usage example
subscribe('userLoggedIn', (userData) => {
console.log('Hello,', userData.name);
});
subscribe('userLoggedIn', (userData) => {
console.log('User', userData.id, 'logged in');
});
publish('userLoggedIn', { id: 123, name: 'Ivan' });