标签:
29.1 策略模式 VS 桥梁模式
29.1.1 策略模式
【编程实验】用策略模式实现邮件发送
(1)有文本和超文本两种格式的邮件,将这两种格式封装成两种不同的发送策略。
(2)文本邮件和超文本邮件分别是两种不同格式的邮件的封装。MailServer是一个环境角色,它接收一个MailTemplate对象,并通过sentMail方法将邮件发送出去。
//跨战区大PK——策略模式和桥接模式 //实例:用策略模式实现邮件发送 #include <iostream> #include <string> using namespace std; //抽象邮件 class MailTemplate { protected: string from; //邮件发件人 string to; //收件人 string subject; //邮件标题 protected: string context; //邮件内容 public: MailTemplate(string from, string to, string subject, string context) { this->from = from; this->to = to; this->subject = subject; this->context = context; } string getFrom(){return from;} void setFrom(string value){from = value;} string getTo(){return to;} void setTo(string value){to = value;} string getSubject(){return subject;} void setSubject(string value){subject = value;} void setContext(string value){context = value;} virtual string getContext() = 0; }; //文本邮件 class TextMail : public MailTemplate { public: TextMail(string from, string to, string subject, string context):MailTemplate(from, to, subject, context) { } string getContext() { //文本类型设置邮件的格式为text/plain context = "\n Context-type: text/plain;charset=GB2312\n" + context; //同时对邮件进行base64编码处理,这里用一句话代替 context += "\n邮件格式为:文本格式"; return context; } }; //超文本邮件 class HtmlMail : public MailTemplate { public: HtmlMail(string from, string to, string subject, string context):MailTemplate(from, to, subject, context) { } string getContext() { //超文本类型设置邮件的格式为multipart/mixed context = "\n Context-type: multipart/mixed;charset=GB2312\n" + context; //同时对邮件进行HTML检查,是否有类似未关闭的标答 context += "\n邮件格式为:超文本格式"; return context; } }; //邮件服务器(环境角色类) class MailServer { private: MailTemplate* mail; public: MailServer(MailTemplate& mt) { mail = &mt; } //发送邮件 void sendMail() { cout << "====正在发送的邮件信息====" << endl; //发件人 cout << "发件人:" << mail->getFrom()<< endl; //收件人 cout << "收件人:" << mail->getTo()<< endl; //邮件标题 cout << "邮件标题:" << mail->getSubject()<< endl; //邮件内容 cout << "邮件内容:" << mail->getContext()<< endl; } }; int main() { //创建一封超文本格式的邮件 MailTemplate* txtMail = new HtmlMail("a@a.com", "b@b.com", "外星人攻击地球了", "结局是外星人被地球人打败了!"); //创建邮件服务器 MailServer mailServ(*txtMail); //发送邮件 mailServ.sendMail(); return 0; }; /*输出结果: ====正在发送的邮件信息==== 发件人:a@a.com 收件人:b@b.com 邮件标题:外星人攻击地球了 邮件内容: Context-type: multipart/mixed;charset=GB2312 结局是外星人被地球人打败了! 邮件格式为:超文本格式 */
29.1.2 桥梁模式
【编程实验】用桥梁模式实现邮件发送
(1)增加了SendMail和Postfix两种邮件服务器的实现类,他们都从MailServer继承。
(2)这样邮件服务器与邮件模板就可以独立变化。
//跨战区大PK——策略模式和桥接模式 //实例:用桥接模式实现邮件发送 #include <iostream> #include <string> using namespace std; //抽象邮件 class MailTemplate { protected: string from; //邮件发件人 string to; //收件人 string subject; //邮件标题 protected: string context; //邮件内容 public: MailTemplate(string from, string to, string subject, string context) { this->from = from; this->to = to; this->subject = subject; this->context = context; } string getFrom(){return from;} void setFrom(string value){from = value;} string getTo(){return to;} void setTo(string value){to = value;} string getSubject(){return subject;} void setSubject(string value){subject = value;} void setContext(string value){context = value;} virtual string getContext() = 0; //允许增加邮件发送标志 void add(string sendInfo) { context =sendInfo + context; } }; //文本邮件 class TextMail : public MailTemplate { public: TextMail(string from, string to, string subject, string context):MailTemplate(from, to, subject, context) { } string getContext() { //文本类型设置邮件的格式为text/plain context = "\nContext-type: text/plain;charset=GB2312\n" + context; //同时对邮件进行base64编码处理,这里用一句话代替 context += "\n邮件格式为:文本格式"; return context; } }; //超文本邮件 class HtmlMail : public MailTemplate { public: HtmlMail(string from, string to, string subject, string context):MailTemplate(from, to, subject, context) { } string getContext() { //超文本类型设置邮件的格式为multipart/mixed context = "\nContext-type: multipart/mixed;charset=GB2312\n" + context; //同时对邮件进行HTML检查,是否有类似未关闭的标答 context += "\n邮件格式为:超文本格式"; return context; } }; //邮件服务器(相当于桥接模式的抽象化角色) class MailServer { protected: MailTemplate* mail; public: MailServer(MailTemplate& mt) { mail = &mt; } //发送邮件 virtual void sendMail() { cout << "====正在发送的邮件信息====" << endl; //发件人 cout << "发件人:" << mail->getFrom()<< endl; //收件人 cout << "收件人:" << mail->getTo()<< endl; //邮件标题 cout << "邮件标题:" << mail->getSubject()<< endl; //邮件内容 cout << "邮件内容:" << mail->getContext()<< endl; } }; //Postfix邮件服务器 class Postfix : public MailServer { public: Postfix(MailTemplate& mt):MailServer(mt){} //修正邮件发送程序 void sendMail() { //增加邮件服务器信息 string context = "Received: from XXXX(unknow[xxx.xxx.xxx.xxx]) by "; context += "aaa.aaa.com(Postfix) with ESMTP id 8DBCD172B8\n"; mail->add(context); MailServer::sendMail(); } }; //SendMail邮件服务器 class SendMail : public MailServer { public: SendMail(MailTemplate& mt):MailServer(mt){} //修正邮件发送程序 void sendMail() { //增加邮件服务器信息 string context = "Received: (sendmail);7 Nov 2016 10:40:00 +100\n"; mail->add(context); MailServer::sendMail(); } }; int main() { //创建一封超文本格式的邮件 MailTemplate* txtMail = new HtmlMail("a@a.com", "b@b.com", "外星人攻击地球了", "结局是外星人被地球人打败了!"); //创建邮件服务器 MailServer* mailServ = new Postfix(*txtMail); //发送邮件 mailServ->sendMail(); return 0; }; /*输出结果: ====正在发送的邮件信息==== 发件人:a@a.com 收件人:b@b.com 邮件标题:外星人攻击地球了 邮件内容: Context-type: multipart/mixed;charset=GB2312 Received: from XXXX(unknow[xxx.xxx.xxx.xxx]) by aaa.aaa.com(Postfix) with ESMTP id 8DBCD172B8 结局是外星人被地球人打败了! 邮件格式为:超文本格式 */
29.1.3 小结
(1)策略模式是一个行为模式,旨在封装一系列的行为。可以把邮件的必要信息封装成一个对象,也就是一个行为,封装的格式不同,行为也就不同。
(2)桥梁模式则是解决在不破坏封装的情况下将抽象和实现部分分离,让他们可以独立变化。
(3)策略模式是使用继承和多态建立一套可以自由切换算法的模式,而桥梁模式必然有两个“桥墩”——抽象化角色和实现化角色,只要桥墩搭建好了,桥就有了。策略模式只有一个抽象角色,可以没有实现,也可以有很多实现。
标签:
原文地址:http://www.cnblogs.com/5iedu/p/5659517.html