如何基于开闭原则优化Python多邮件平台发送逻辑?
优化邮件平台分发的实现方案
首先修正原代码里的一个小问题:Gmail和HotMail类应该继承自Email抽象类,而非直接继承ABC——因为Email已经是基于ABC定义的抽象基类,这样才能保证所有邮件平台类遵循统一的接口规范。
针对你提到的「新增平台需修改lambda_handler分支」的问题,最常用的优化方案是用字典映射实现工厂模式,将平台名称与对应类绑定,避免冗长的条件判断。
优化后的基础版本代码
from abc import ABC, abstractmethod import json class Email(ABC): @abstractmethod def sendEmail(self): pass class Gmail(Email): def sendEmail(self): # 具体发送逻辑 return "Sent to gmail" class HotMail(Email): def sendEmail(self): # 具体发送逻辑 return "Sent to hotmail" # 建立平台名称到类的映射字典 MAIL_PLATFORMS = { 'gmail': Gmail, 'hotmail': HotMail } def lambda_handler(event, context): info = json.loads(event['body']) mail_platform = info['type'] # 通过映射直接获取类并实例化 MailClass = MAIL_PLATFORMS.get(mail_platform) if not MailClass: # 处理未知平台的异常情况 return {"statusCode": 400, "body": json.dumps("Unsupported mail platform")} mail = MailClass() mail.sendEmail() return {"statusCode": 200, "body": json.dumps("Email sent successfully")}
新增平台的操作步骤
当需要新增Yahoo这类新平台时,仅需两步:
- 新增对应类并实现接口:
class Yahoo(Email): def sendEmail(self): # Yahoo邮件发送逻辑 return "Sent to yahoo"
- 在
MAIL_PLATFORMS字典中添加映射:
MAIL_PLATFORMS['yahoo'] = Yahoo
完全不需要修改lambda_handler内的逻辑,符合「开闭原则」——对扩展开放,对修改关闭。
进阶优化:自动注册类
如果觉得手动维护映射字典麻烦,可以用装饰器实现类的自动注册,进一步降低维护成本:
from abc import ABC, abstractmethod import json class Email(ABC): @abstractmethod def sendEmail(self): pass MAIL_PLATFORMS = {} def register_mail_platform(platform_name): def decorator(cls): MAIL_PLATFORMS[platform_name] = cls return cls return decorator @register_mail_platform('gmail') class Gmail(Email): def sendEmail(self): return "Sent to gmail" @register_mail_platform('hotmail') class HotMail(Email): def sendEmail(self): return "Sent to hotmail" # 新增Yahoo时,仅需添加类和装饰器 @register_mail_platform('yahoo') class Yahoo(Email): def sendEmail(self): return "Sent to yahoo" def lambda_handler(event, context): info = json.loads(event['body']) mail_platform = info['type'] MailClass = MAIL_PLATFORMS.get(mail_platform) if not MailClass: return {"statusCode": 400, "body": json.dumps("Unsupported mail platform")} mail = MailClass() mail.sendEmail() return {"statusCode": 200, "body": json.dumps("Email sent successfully")}
内容的提问来源于stack exchange,提问作者user12073359
相关产品推荐
相关产品推荐

