戏说设计模式-工厂模式
来源:互联网 发布:自制选择题软件 编辑:程序博客网 时间:2024/05/17 07:49
今天一大早,经理就把老罗和小杨召集起来,说:今天的主要任务是在我们的平台中加上用户注册的功能。用户填写基本资料,其中包含手机号,要确保是一个真实的手机,所以要用验证码,注册成功后,平台发一封邮件到他的邮箱里面。老罗,你负责调研、编写手机验证码,发邮件的部分。小杨,你负责界面和业务流程部分。说完,大家就各自开工了。
下午的时候,老罗对小杨说:发邮件发短信的功能,我都帮你写好了,分别在utils.MailSender和utils.SMSSender里面,已经push到gitlab上了。
“知道了,我一会儿调一下试试。”小杨自己的部分还没有做完,头也不抬的回应着。
过了一会儿,小杨对老罗喊了一声:“老罗,发邮件报错了,空指针,我发给你报错信息。“
“空指针?我自己测试过的啊!”
老罗,根据报错信息中提示的错误行数找到相应的代码研究起来,然后又运行了一遍他的测试程序,发现并没有错,然后就到小杨座位上想看看是怎么回事。他看到小样的代码,下意识地喊了一句:“你调错了,少写一行代码,我说怎么我那边不报错。”随后,老罗打开自己的代码,还跟小杨解释说
这是发送工具接口,就一个方法
public interface Sender { void send(String from,String to,String subject,String content);}这是发短信工具的实现类,SMSSender,我用的淘宝的工具类
import com.taobao.api.ApiException;import com.taobao.api.DefaultTaobaoClient;import com.taobao.api.TaobaoClient;import com.taobao.api.request.AlibabaAliqinFcSmsNumSendRequest;import com.taobao.api.response.AlibabaAliqinFcSmsNumSendResponse;public class SmsSender implements Sender{ public static final String SMS_SEND_URL = "http://gw.api.taobao.com/router/rest"; public static final String APPKEY = "xxxx"; public static final String SECRET = "xxxxxxxx"; public static final String SIGN = "测试"; @Override public void send(String from, String to, String subject, String content){ TaobaoClient client = new DefaultTaobaoClient(SMS_SEND_URL, APPKEY, SECRET); AlibabaAliqinFcSmsNumSendRequest req = new AlibabaAliqinFcSmsNumSendRequest(); //req.setExtend("123456"); req.setSmsType("normal"); req.setSmsFreeSignName(SIGN); req.setSmsParamString(content); req.setRecNum(to); req.setSmsTemplateCode("10010"); AlibabaAliqinFcSmsNumSendResponse rsp = null; try { rsp = client.execute(req); } catch (ApiException e) { e.printStackTrace(); } }}
这是邮件工具的实现类,MailSender
package factory;import javax.mail.*;import javax.mail.internet.AddressException;import javax.mail.internet.InternetAddress;import javax.mail.internet.MimeMessage;import javax.mail.Message.RecipientType;import java.util.Calendar;import java.util.Properties;/** * Created by user on 2016/8/18. */public class MailSender implements Sender { Properties props = new Properties(); public Properties config(String smtpHost,String starttls,String auth,String password){ props.put("mail.smtp.host", smtpHost); props.put("mail.smtp.starttls.enable",starttls);//使用 STARTTLS安全连接 props.put("mail.smtp.auth", auth);// 使用验证 props.put("mail.smtp.password", auth);// 密码 return props; } @Override public void send(String from,String to,String subject,String content) { Session mailSession = Session.getInstance(props,new MyAuthenticator(from,props.getProperty("mail.smtp.password"))); Transport transport = null; try { transport = mailSession.getTransport("smtp"); } catch (NoSuchProviderException e) { e.printStackTrace(); } InternetAddress fromAddress = null; InternetAddress toAddress = null; try { fromAddress = new InternetAddress(from); toAddress = new InternetAddress(to); } catch (AddressException e) { e.printStackTrace(); } MimeMessage message = new MimeMessage(mailSession); try { message.setFrom(fromAddress); message.addRecipient(RecipientType.TO, toAddress); message.setSentDate(Calendar.getInstance().getTime()); message.setSubject(subject); message.setContent(content, "text/html;charset=gb2312"); transport.connect(props.getProperty("mail.smtp.host"),from, props.getProperty("mail.smtp.password")); transport.send(message, message.getRecipients(RecipientType.TO)); } catch (MessagingException e) { e.printStackTrace(); } } class MyAuthenticator extends Authenticator { String userName=""; String password=""; public MyAuthenticator(){ } public MyAuthenticator(String userName,String password){ this.userName=userName; this.password=password; } protected PasswordAuthentication getPasswordAuthentication(){ return new PasswordAuthentication(userName, password); } }}“你看看你是怎么调用的”
MailSender mailSender = new MailSender();mailSender.send("j1@tm.com","j2@tm.com","谢谢","谢谢注册");“调用send之前应该要调用一下config方法,输入一些配置信息啊”。老罗埋怨小杨道。
"我哪里知道要先调用一下config方法"小杨有些委屈。
老罗突然意识到,小杨并没有看过自己的代码,不过还是说了一句:“调之前你看一下嘛”
“我那边功能还没做完呢。”小杨听到这句话,感到一股怒火油然而生,但还是压住了怒火,因为他感到老罗在推卸责任。
“就算是你不知道我怎么实现的,报错后也可以调试一下吧,这么简单一个代码,调试一下就明白了啊,没见过这么笨的”。
“你代码报错了还让我调试”。
“我那边没报错,到你这就报错了,你还不承认是你的问题?”。老罗非常确信的认为这个问题是小杨的问题
“你写那垃圾代码,我根本不稀罕看,说我笨?我用过spark,信不信老子弄死你”,小杨完全不想跟老罗纠缠了,语调上扬。
老罗被小杨的话震惊了,撒腿就跑到经理办公室,推开门喊道:“经理,小杨要弄死我......”。
经理看到狼狈的老罗,被突如其来的场景吓了一跳,手忙脚乱的关掉直播软件,同时问到:“什...什么?”老罗把刚才发生的一幕告诉了经理。经理跟着老罗来到了小杨的座位旁,看了看他们俩的代码,说到:“小杨,大家都是同事,干嘛要说弄死谁的呢,有话好好说嘛,老罗,你也是,都是老员工了,你任务做的快,也要好好的思考一下,能否优化呢,怎么总是不注意呢!你代码本身没什么问题,但是你忽略了一件事情,就是一个项目是团队协作完成的,要尽量的站在队友的角度看问题嘛,你调研完成了代码,但是别人没有经历过你代码完成的过程,他们并没有思考过你曾经思考过的问题,有很多细节他们是不知道的,你认为这样调用代码是理所当然的,但别人不一定是这样想的啊”
"那我总不能每次写完自己的代码,都要跟别人从头到尾讲一遍吧,我想讲,他们也不一定想听啊,就算是他们想听,也不一定能听懂啊,你说是不是",老罗看着小杨说。
小杨正想反击,经理按住他说:“呵呵,别人确实不想知道你代码的细节,不过你也不要把责任推卸给别人,你的代码稍微改一下就不会发生刚才的扯皮事件,你看好,我来改一下”。说着,经理坐在了座位上亲自动手改了起来,边改边解释。
首先,我们把MailSender改造一下,让他的配置用的props可以从外部类访问
package factory;import javax.mail.*;import javax.mail.internet.AddressException;import javax.mail.internet.InternetAddress;import javax.mail.internet.MimeMessage;import javax.mail.Message.RecipientType;import java.util.Calendar;import java.util.Properties;/** * Created by user on 2016/8/18. */public class MailSender implements Sender { private Properties props = null; public Properties getProps() { return props; } public void config(String smtpHost, String starttls, String auth, String password){ props.put("mail.smtp.host", smtpHost); props.put("mail.smtp.starttls.enable",starttls);//使用 STARTTLS安全连接 props.put("mail.smtp.auth", auth);// 使用验证 props.put("mail.smtp.password", auth);// 密码 } @Override public void send(String from,String to,String subject,String content) { if(props == null){ config("smtp.gmail.com","true","true","admin_password"); } Session mailSession = Session.getInstance(props,new MyAuthenticator(from,props.getProperty("mail.smtp.password"))); Transport transport = null; try { transport = mailSession.getTransport("smtp"); } catch (NoSuchProviderException e) { e.printStackTrace(); } InternetAddress fromAddress = null; InternetAddress toAddress = null; try { fromAddress = new InternetAddress(from); toAddress = new InternetAddress(to); } catch (AddressException e) { e.printStackTrace(); } MimeMessage message = new MimeMessage(mailSession); try { message.setFrom(fromAddress); message.addRecipient(RecipientType.TO, toAddress); message.setSentDate(Calendar.getInstance().getTime()); message.setSubject(subject); message.setContent(content, "text/html;charset=gb2312"); transport.connect(props.getProperty("mail.smtp.host"),from, props.getProperty("mail.smtp.password")); transport.send(message, message.getRecipients(RecipientType.TO)); } catch (MessagingException e) { e.printStackTrace(); } } class MyAuthenticator extends Authenticator { String userName=""; String password=""; public MyAuthenticator(){ } public MyAuthenticator(String userName,String password){ this.userName=userName; this.password=password; } protected PasswordAuthentication getPasswordAuthentication(){ return new PasswordAuthentication(userName, password); } }}
我们把实例化的工作放到另外一个类中,并且提供一个方法根据参数进行实例化。
public class SimpleSenderFactory { public enum SENDER_TYPE{ MAIL,SMS } public static Sender product(SENDER_TYPE senderType){ if(senderType == SENDER_TYPE.SMS){ return new SmsSender(); }else if(senderType == SENDER_TYPE.MAIL){ MailSender mailSender = new MailSender(); mailSender.config("smtp.gmail.com","true","true","password"); return mailSender; }else{ return null; } }}
这样,我们把实例化的职责从使用方拿了回来。接下来看如何使用
Sender sender = SimpleSenderFactory.product(SimpleSenderFactory.SENDER_TYPE.MAIL);sender.send("j3@tm.com","j4@tm.com","你好","欢迎");虽然,还是要对使用方说明SimpleSenderFactory的使用方式,但无疑他屏蔽了发邮件的实现细节。SimpleSenderFactory是一个工厂类,他负责产生Sender产品,发邮件工具类和发短信工具类都是他的具体产品,SimpleSenderFactory把这些产品的实例化方法都管理起来,不过呢,将来新增一个Sender类型的产品,就需要修改SimpleSenderFactory,这也是他的一个缺点。
- 戏说设计模式-工厂模式
- 戏说设计模式-工厂方法
- 戏说模式3-工厂
- 戏说设计模式(四)简单工厂模式
- 戏说设计模式(五)工厂方法模式
- 戏说设计模式(六)抽象工厂模式
- 戏说设计模式(转帖)
- 戏说设计模式
- 戏说设计模式
- 戏说GoF设计模式
- 戏说23种设计模式
- 戏说模式-追MM与设计模式
- 戏说java设计模式中的命令模式
- 设计模式-Factory模式戏说
- 设计模式-AbstractFactory模式戏说
- 设计模式-Singleton模式戏说
- 设计模式-Builder模式戏说
- 设计模式-Prototype模式戏说
- 手机照片误删怎么找回
- eclipse起动无响应,停留在Loadingworkbench状态
- [李景山php]每天laravel-20161017|UploadedFile.php
- FZU 最大黑区域
- 解决:System.Data.SqlClient.SqlException: 超出了存储过程、函数、触发器或视图的最大嵌套层数(最大层数为 32).
- 戏说设计模式-工厂模式
- 关注状态栏标题栏的显示与隐藏
- JQuery中serialize()、serializeArray()和param()方法示例介绍
- UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-4: ordinal not in range(128)
- ADAS高级驾驶辅助系统浅解答
- Framework7中利用download和external实现a标签下载文件和图片
- Html Dom(动态页面的基础)的基本了解
- 关于新建项目如何传至svn
- FZU 翻翻棋