JavaScript 设计模式 - 充当管理器并调用不同方法的方法
JavaScript Design Patterns - Method which behaves as a manager and call different methods
简介
我的应用程序有不同的功能,例如:
- 重设密码(忘记密码)
- 更新用户密码
- 注册
- 成为溢价
对于每个功能,当成功时,我想向用户发送自定义 HTML 电子邮件。
生成电子邮件
由于HTML主要结构相同(只是内容(文本)发生变化),我决定实现我的辅助方法generateEmailTemplate()
:
const { HEAD, BODY } = require("../utils");
module.exports = (main) => `
<!DOCTYPE html>
<html lang="en">
${HEAD}
${BODY(main)}
</html>
`;
并且,为了将特定数据包含到生成的模板中,我对每个功能使用不同的方法:
const signUpWelcomeEmailTemplate = (name) =>
templateGenerator(`<p>Welcome, ${name}</p>`);
const premiumEmailTemplate = (name) =>
templateGenerator(`<h1>${name}, you are now premium!</h1>`);
// The html is more complex, I have reduced it for simiplicity
正在发送电子邮件
为了向用户发送电子邮件,我有以下方法,它将电子邮件记录添加到我的数据库中。然后,当添加记录时,连接到 MailGun
服务的自定义扩展通过 SMTP 发送邮件。
这是我的方法的实现:
async function sendEmail(
to,
subject,
text = undefined,
html = undefined
) {
const mailsRef = db.collection("mails");
const mail = {
to,
message: {
subject,
...text && { text },
...html && { html },
},
};
await mailsRef.add(mail);
functions.logger.log("Queued email for delivery!");
};
问题
现在,为了使用此方法,在每个功能中,我必须执行以下操作:
async function goPremium(user) {
try {
await purchasePremium(user.uid);
const html = premiumEmailTemplate(user.name);
sendEmail(user.email, "Premium purchase success!", undefined, html);
} catch(err) {
...
}
}
我正在寻找一种概括此调用的模式,我的意思是,某种电子邮件管理器。
我想过两种不同的方法来重构这段代码:
#1(我不喜欢这种方式,因为方法可能超长,我的意思是,想象一下 100 个特征...)
function emailManager(user, type) {
switch(type) {
"welcome":
sendEmail(user.email, "Welcome!", undefined, welcomeEmailTemplate(user.name));
break;
"premium":
sendEmail(user.email, "Premium purchase success!", undefined, premiumEmailTemplate(user.name));
break;
default:
break;
}
}
- 只需创建不同的方法并从 'central' 模块导出它们。
...
const sendPremiumEmail = (user) => {
const title = "Premium purchase success!";
const html = premiumEmailTemplate(user.name);
return sendEmail(user.email, title, undefined, html);
};
...
module.exports = {
sendWelcomeEmail,
sendPremiumEmail,
...
}
但是...也许还有另一种方法,一种模式可以完全解决这种情况。有什么想法吗?
函数式风格 -- 定义 curried 函数 sendEmail
并为高级电子邮件和欢迎电子邮件制作两个部分应用程序。
const sendEmail = (subject, template) => to => {
const mailsRef = db.collection("mails");
const html = template(to);
const mail = {
to,
message: {
subject,
...text && { text }, // unused
...html && { html },
},
};
await mailsRef.add(mail);
functions.logger.log("Queued email for delivery!");
}
const sendPremiumEmail = sendEmail("Premium purchase success!", premiumEmailTemplate);
const sendWelcomeEmail = sendEmail("Welcome", welcomeEmailTemplate);
// usage
await sendPremiumEmail('foo@email.com');
简介
我的应用程序有不同的功能,例如:
- 重设密码(忘记密码)
- 更新用户密码
- 注册
- 成为溢价
对于每个功能,当成功时,我想向用户发送自定义 HTML 电子邮件。
生成电子邮件
由于HTML主要结构相同(只是内容(文本)发生变化),我决定实现我的辅助方法generateEmailTemplate()
:
const { HEAD, BODY } = require("../utils");
module.exports = (main) => `
<!DOCTYPE html>
<html lang="en">
${HEAD}
${BODY(main)}
</html>
`;
并且,为了将特定数据包含到生成的模板中,我对每个功能使用不同的方法:
const signUpWelcomeEmailTemplate = (name) =>
templateGenerator(`<p>Welcome, ${name}</p>`);
const premiumEmailTemplate = (name) =>
templateGenerator(`<h1>${name}, you are now premium!</h1>`);
// The html is more complex, I have reduced it for simiplicity
正在发送电子邮件
为了向用户发送电子邮件,我有以下方法,它将电子邮件记录添加到我的数据库中。然后,当添加记录时,连接到 MailGun
服务的自定义扩展通过 SMTP 发送邮件。
这是我的方法的实现:
async function sendEmail(
to,
subject,
text = undefined,
html = undefined
) {
const mailsRef = db.collection("mails");
const mail = {
to,
message: {
subject,
...text && { text },
...html && { html },
},
};
await mailsRef.add(mail);
functions.logger.log("Queued email for delivery!");
};
问题
现在,为了使用此方法,在每个功能中,我必须执行以下操作:
async function goPremium(user) {
try {
await purchasePremium(user.uid);
const html = premiumEmailTemplate(user.name);
sendEmail(user.email, "Premium purchase success!", undefined, html);
} catch(err) {
...
}
}
我正在寻找一种概括此调用的模式,我的意思是,某种电子邮件管理器。
我想过两种不同的方法来重构这段代码:
#1(我不喜欢这种方式,因为方法可能超长,我的意思是,想象一下 100 个特征...)
function emailManager(user, type) {
switch(type) {
"welcome":
sendEmail(user.email, "Welcome!", undefined, welcomeEmailTemplate(user.name));
break;
"premium":
sendEmail(user.email, "Premium purchase success!", undefined, premiumEmailTemplate(user.name));
break;
default:
break;
}
}
- 只需创建不同的方法并从 'central' 模块导出它们。
...
const sendPremiumEmail = (user) => {
const title = "Premium purchase success!";
const html = premiumEmailTemplate(user.name);
return sendEmail(user.email, title, undefined, html);
};
...
module.exports = {
sendWelcomeEmail,
sendPremiumEmail,
...
}
但是...也许还有另一种方法,一种模式可以完全解决这种情况。有什么想法吗?
函数式风格 -- 定义 curried 函数 sendEmail
并为高级电子邮件和欢迎电子邮件制作两个部分应用程序。
const sendEmail = (subject, template) => to => {
const mailsRef = db.collection("mails");
const html = template(to);
const mail = {
to,
message: {
subject,
...text && { text }, // unused
...html && { html },
},
};
await mailsRef.add(mail);
functions.logger.log("Queued email for delivery!");
}
const sendPremiumEmail = sendEmail("Premium purchase success!", premiumEmailTemplate);
const sendWelcomeEmail = sendEmail("Welcome", welcomeEmailTemplate);
// usage
await sendPremiumEmail('foo@email.com');