Problem: Inject Configuration into a Decorator

Medium
30 min
Build a decorator factory that logs messages with a configurable prefix.

Problem statement

Our team wants consistent logging across multiple modules, but each module should have its own prefix (for example, [USER][ORDER][PAYMENT]). Instead of hardcoding prefixes in every decorator, we’ll build a configurable decorator factory that injects the prefix dynamically. This is a key evolution of the decorator pattern. It allows us to wrap functions with context-aware behavior.

Goal

Create a decorator factory createLogger(prefix) that:

  • Returns a decorator function.

  • That decorator, when applied, logs a prefixed message before and after the original function runs.

  • Works with both sync and async functions.

Constraints

  • Do not modify the original function logic.

  • The factory must return a new decorator each time it’s called.

  • The decorator must log both before and after execution.

  • Use string interpolation for clarity (e.g., [USER] Called with args: ...).

Sample output

The examples below illustrate what the output should look like:

const withUserLogging = createLogger('[USER]');
const loggedFetchOrder = withUserLogging(fetchOrder);
(async () => {
await loggedFetchOrder(42);
})();
/* Expected output:
[USER] Called with args: [42]
[USER] Returned: { id: 42, total: 99 } */

Good luck trying the problem! If you’re unsure how to proceed, check the “Solution” tab above.

Problem: Inject Configuration into a Decorator

Medium
30 min
Build a decorator factory that logs messages with a configurable prefix.

Problem statement

Our team wants consistent logging across multiple modules, but each module should have its own prefix (for example, [USER][ORDER][PAYMENT]). Instead of hardcoding prefixes in every decorator, we’ll build a configurable decorator factory that injects the prefix dynamically. This is a key evolution of the decorator pattern. It allows us to wrap functions with context-aware behavior.

Goal

Create a decorator factory createLogger(prefix) that:

  • Returns a decorator function.

  • That decorator, when applied, logs a prefixed message before and after the original function runs.

  • Works with both sync and async functions.

Constraints

  • Do not modify the original function logic.

  • The factory must return a new decorator each time it’s called.

  • The decorator must log both before and after execution.

  • Use string interpolation for clarity (e.g., [USER] Called with args: ...).

Sample output

The examples below illustrate what the output should look like:

const withUserLogging = createLogger('[USER]');
const loggedFetchOrder = withUserLogging(fetchOrder);
(async () => {
await loggedFetchOrder(42);
})();
/* Expected output:
[USER] Called with args: [42]
[USER] Returned: { id: 42, total: 99 } */

Good luck trying the problem! If you’re unsure how to proceed, check the “Solution” tab above.

Node.js
// Example service
async function fetchOrder(orderId) {
return new Promise((resolve) => {
setTimeout(() => resolve({ id: orderId, total: 99 }), 50);
});
}
// Your code here
// Example usage
const withUserLogging = createLogger('[USER]');
const loggedFetchOrder = withUserLogging(fetchOrder);
(async () => {
await loggedFetchOrder(42);
})();
/* Expected output:
[USER] Called with args: [42]
[USER] Returned: { id: 42, total: 99 } */