Problem: Implement a Config-Driven Notification Service Factory

Medium
30 min
Create a notification factory that builds the correct service (email, SMS, or push) from a nested config object.

Problem statement

Your app supports multiple notification channels—Email, SMS, and Push. The active channel is defined in a nested config object like:

const config = {
notifications: {
channel: 'sms'
}
}

The team wants to support swappable notification implementations without changing call sites. Consumers should call createNotificationService(config) and get the right service. Each service has a .send(msg) method with distinct output. You must also ensure the factory is robust: if an unknown channel is specified, it should throw clearly.

Goal

Implement createNotificationService(config) that returns an instance of the correct service, based on config.notifications.channel.

Constraints

  • Do not use conditionals (if, switch, ternaries) to select which class to instantiate.

  • Must throw if config has an unsupported channel.

  • No service class instantiation outside the factory.

Sample output

The examples below illustrate what the output should look like:

const smsConfig = { notifications: { channel: 'sms' } };
const smsNotifier = createNotificationService(smsConfig);
console.log(smsNotifier.send('Welcome via SMS'));
/* Expected output:
SMS: Welcome via SMS */
const emailConfig = { notifications: { channel: 'email' } };
const emailNotifier = createNotificationService(emailConfig);
console.log(emailNotifier.send('Welcome via Email'));
/* Expected output:
Email: Welcome via Email */
const pushConfig = { notifications: { channel: 'push' } };
const pushNotifier = createNotificationService(pushConfig);
console.log(pushNotifier.send('Welcome via Push'));
/* Expected output:
Push: Welcome via Push */

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

Problem: Implement a Config-Driven Notification Service Factory

Medium
30 min
Create a notification factory that builds the correct service (email, SMS, or push) from a nested config object.

Problem statement

Your app supports multiple notification channels—Email, SMS, and Push. The active channel is defined in a nested config object like:

const config = {
notifications: {
channel: 'sms'
}
}

The team wants to support swappable notification implementations without changing call sites. Consumers should call createNotificationService(config) and get the right service. Each service has a .send(msg) method with distinct output. You must also ensure the factory is robust: if an unknown channel is specified, it should throw clearly.

Goal

Implement createNotificationService(config) that returns an instance of the correct service, based on config.notifications.channel.

Constraints

  • Do not use conditionals (if, switch, ternaries) to select which class to instantiate.

  • Must throw if config has an unsupported channel.

  • No service class instantiation outside the factory.

Sample output

The examples below illustrate what the output should look like:

const smsConfig = { notifications: { channel: 'sms' } };
const smsNotifier = createNotificationService(smsConfig);
console.log(smsNotifier.send('Welcome via SMS'));
/* Expected output:
SMS: Welcome via SMS */
const emailConfig = { notifications: { channel: 'email' } };
const emailNotifier = createNotificationService(emailConfig);
console.log(emailNotifier.send('Welcome via Email'));
/* Expected output:
Email: Welcome via Email */
const pushConfig = { notifications: { channel: 'push' } };
const pushNotifier = createNotificationService(pushConfig);
console.log(pushNotifier.send('Welcome via Push'));
/* Expected output:
Push: Welcome via Push */

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

Node.js
// JavaScript boilerplate
class EmailService {
send(msg) {
return `Email: ${msg}`;
}
}
class SMSService {
send(msg) {
return `SMS: ${msg}`;
}
}
class PushService {
send(msg) {
return `Push: ${msg}`;
}
}
// Implement this
function createNotificationService(config) {
// Return correct service or throw if invalid
}
// Example usage
const smsConfig = { notifications: { channel: 'sms' } };
const smsNotifier = createNotificationService(smsConfig);
console.log(smsNotifier.send('Welcome via SMS'));
/* Expected output:
SMS: Welcome via SMS */
const emailConfig = { notifications: { channel: 'email' } };
const emailNotifier = createNotificationService(emailConfig);
console.log(emailNotifier.send('Welcome via Email'));
/* Expected output:
Email: Welcome via Email */
const pushConfig = { notifications: { channel: 'push' } };
const pushNotifier = createNotificationService(pushConfig);
console.log(pushNotifier.send('Welcome via Push'));
/* Expected output:
Push: Welcome via Push */