使用模板模式和工厂模式的混合设计开发各种邮件客户端发送邮件

使用模板模式和工厂模式的混合设计开发各种邮件客户端发送邮件。

模板模式的目的:能保证快速开发各种邮箱客户端,子类只需要重写邮箱的登陆方法即可。

工厂模式的目的:能隐藏创建具体对象的细节,只需从工厂类的方法中就能得到各种邮箱客户端。例如被别的模块import时候,只需要import这个工厂类就可以了,不需要去import几十种具体的邮箱客户端。

# coding=utf8
"""
使用模板模式、工厂模式的混合设计,开发各种邮件客户端
"""
import sys

reload(sys)
sys.setdefaultencoding('utf8')

from abc import ABCMeta, abstractmethod
import smtplib
from email.mime.text import MIMEText


class MailClient(object):
    """一个通用的邮件客户端,作为模板模式的模板类。
    该类为抽象类,不可以进行实例化。
    _login方法为抽象方法,子类必须重写这个方法
    """
    __metaclass__ = ABCMeta

    def __init__(self, msg_from, passwd):
        """
        :param msg_from: 发件人邮箱地址
        :param passwd: 发件人邮箱密码,qq邮箱使用授权码是16个字母,而不是自己的邮箱密码。
        """
        self._msg_from = msg_from
        self._passwd = passwd
        self._smtp = None
        self._login()

    @abstractmethod
    def _login(self):
        pass

    def send_mail(self, msg_to, subject, content):
        """
        发送邮件
        :param msg_to: 收件人邮箱地址
        :param subject :邮件主题
        :param content:邮件内容
        :type msg_to:str
        :type subject:str
        :type content:str
        """
        msg = MIMEText(content, _charset='utf8')
        msg['Subject'] = subject
        msg['From'] = self._msg_from
        msg['To'] = msg_to
        self._smtp.sendmail(self._msg_from, msg_to, msg.as_string())

    def quit(self):
        self._smtp.quit()

    def __del__(self):
        self.quit()


class QQMailClient(MailClient):
    def _login(self):
        self._smtp = smtplib.SMTP_SSL("smtp.qq.com", 465)
        self._smtp.login(self._msg_from, self._passwd)


class Wangyi163MailClient(MailClient):
    def _login(self):
        self._smtp = smtplib.SMTP_SSL("smtp.163.com", 465)
        self._smtp.login(self._msg_from, self._passwd)


class MailClientFactory(object):
    @staticmethod
    def get_mail_client(mail_name, msg_from, passwd):
        """
        :param mail_name: 邮箱名称,为‘163’是网易邮箱,为‘qq’是QQ邮箱
        :param msg_from:发件人邮箱地址
        :param passwd:邮箱密码
        :return: 具体的邮箱对象
        :type mail_name:str
        :type msg_from:str
        :type passwd:str
        :rtype :MailClient
        """
        if mail_name == '163':
            return Wangyi163MailClient(msg_from, passwd)
        elif mail_name.upper() == 'QQ':
            return QQMailClient(msg_from, passwd)
        else:
            raise Exception('设置的邮箱种类不存在')


if __name__ == "__main__":
    wangyi163_mail_client = MailClientFactory.get_mail_client('163', '[email protected]', '123456')
    wangyi163_mail_client.send_mail('[email protected]', '测试网易163邮箱发送主题1', '测试网易163邮箱发送内容1')
    wangyi163_mail_client.send_mail('[email protected]', '测试网易163邮箱发送主题2', '测试网易163邮箱发送内容2')

    qq_mail_client = MailClientFactory.get_mail_client('qq', '[email protected]', 'ssoodruxniyfbxxx')
    qq_mail_client.send_mail('[email protected]', '测试qq邮箱发送主题3', '测试qq邮箱发送内容3')

由此可见,在一个项目中设计模式不是固定的只能用一种,而是可以多种模式混合设计,这需要多练习。23种模式就像独孤九剑,各种招式的结合变幻无穷。

猜你喜欢

转载自www.cnblogs.com/ydf0509/p/8976025.html