DIY迷你邮件客户端的开发结束了,现在完全可以Shift+Delete掉这个工程了。享受这个过程已经完整的进行完了,剩下的问题应该算是总结这个工程。
在 DIY迷你邮件客户端开发手记(一)中已经很勇敢的面对了失败的开始,然后在不好的开端下进行一步一步的修正,过程很惨,结果呢?开始的激动全没有了,剩下最后这两篇文字和在一大堆代码中被狂砍剩下来的几十代码。
在DIY迷你邮件客户端开发手记(二)总结和思考了关于“一”中提到的几个问题。生活和工作中没有如果,发生了就该面对,重读《编码匠艺》,消除不必要的如果,珍惜碎屑时间,换取和MM的共度的美好时光,苦逼真是自找的啦。
1. 关于测试和实验
实验: 经常会面临一个问题就是要实现某一功能,但是有不确定能否一次性就能够实现,这时候就得停下脚步,做一些较为简单的例子,进行技术上的实验,通过的简单的实验可以节省时间,并且有利于技术的确认,增强开发信心。
测试:测试应该是伴随整个开发过程的,而且非常有必要将测试深入,严格的渗透到我们的开发过程中去。每一个模块就要存在相关的测试代码,并且确保已经完成的部分能够直接作为成品集成到项目中。
体会:保留测试代码有利于复查和实时测试
2.提取共同,抽象业务
面向对象的圣经可是絮叨的像祥林嫂一样被念叨,然而不正真感受抽象的重要性,是很难懂得其中的智慧。
PS:在起初设计这个邮件发送的时候同样使用了策略模式,可是最后发现不是这么回事,因为没一份邮件都有一个共同点,邮件服务器,用户名,密码,主题,联系人等。对于普通邮件和附件邮件的区别也仅仅在附件方面处理有所不同而已。
抽象出了严重的问题,导致整个工作进展停滞不前,不停的改动,组织最后还是需要足够的魄力来个Shift+Delete结束过多的纠结,这样就有了后面的事了。学习了一下commons-email-1.x的实现思路,重新对发送邮件进行了包装,这样解决了不同类型邮件的发送问题,收件人电子邮件地址加载问题。
编码:使用EmailContext类对其进行了相应的处理。
- public class EmailContext {
- private Map<String, String> setMap = null;
- private List<String> contactsList = null;
- private Map<String, String> contentsEmail = null;
- private MultiPartEmail mutEmailObject = null;
- private SimpleEmail simEmailObject = null;
- private File[] attactFiles = null;
- /**
- * 获取发送邮件实例对象
- *
- * @param setMap
- * @param contactsList
- * @param contentsEmail
- * @param attactFiles
- *
- */
- public EmailContext(Map<String, String> setMap, List<String> contactsList, Map<String, String> contentsEmail, File[] attactFiles) {
- this.attactFiles = attactFiles;
- this.setMap = setMap;
- this.contentsEmail = contentsEmail;
- this.contactsList = contactsList;
- if (this.attactFiles != null) {
- mutEmailObject = new MultiPartEmail();
- }
- if (this.attactFiles == null) {
- simEmailObject = new SimpleEmail();
- }
- }
- /**
- * 发送电子邮件
- *
- * @return String
- */
- public String sendEmail() {
- String result = "发送失败";
- try {
- if (mutEmailObject != null) {
- setMultiPartEmailMessage();
- result = mutEmailObject.send();
- }
- if (simEmailObject != null) {
- setSimpleEmailMessage();
- result = simEmailObject.send();
- }
- } catch (EmailException ex) {
- Logger.getLogger(EmailContext.class.getName()).log(Level.SEVERE, null, ex);
- JOptionPane.showMessageDialog(null, result, "提示", JOptionPane.INFORMATION_MESSAGE);
- }
- if (!result.equals("发送失败")) {
- result = "发送成功";
- }
- return result;
- }
- /**
- * 设置带附件发送邮件信息
- */
- private void setMultiPartEmailMessage() {
- /**
- * 设置发件人信息
- */
- try {
- mutEmailObject.setAuthentication(setMap.get("userName"), setMap.get("userPwd"));
- mutEmailObject.setHostName(setMap.get("hostName"));
- mutEmailObject.setFrom(setMap.get("from"));
- } catch (EmailException ex) {
- Logger.getLogger(EmailContext.class.getName()).log(Level.SEVERE, null, ex);
- JOptionPane.showMessageDialog(null, "提示", "发件人信息加载失败", JOptionPane.INFORMATION_MESSAGE);
- }
- /**
- * 设置收件人信息
- */
- for (int i = 0, j = contactsList.size(); i < j; i++) {
- try {
- mutEmailObject.addTo(contactsList.get(i));
- } catch (EmailException ex) {
- Logger.getLogger(EmailContext.class.getName()).log(Level.SEVERE, null, ex);
- JOptionPane.showMessageDialog(null, "提示", "联系人信息加载失败", JOptionPane.INFORMATION_MESSAGE);
- }
- }
- /**
- * 设置发送附件信息
- */
- EmailAttachment attact = null;
- for (int i = 0, j = attactFiles.length; i < j; i++) {
- try {
- attact = new EmailAttachment();
- attact.setPath(attactFiles[i].getAbsolutePath());
- mutEmailObject.attach(attact);
- } catch (EmailException ex) {
- Logger.getLogger(EmailContext.class.getName()).log(Level.SEVERE, null, ex);
- JOptionPane.showMessageDialog(null, "提示", "附件加载失败", JOptionPane.INFORMATION_MESSAGE);
- }
- }
- /**
- * 设置邮件内容信息
- */
- try {
- mutEmailObject.setSubject(contentsEmail.get("theme"));
- mutEmailObject.setMsg(contentsEmail.get("contents"));
- } catch (EmailException ex) {
- Logger.getLogger(EmailContext.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
- /**
- * 设置发送邮件信息
- */
- private void setSimpleEmailMessage() {
- /**
- * 设置发件人信息
- */
- try {
- simEmailObject.setAuthentication(setMap.get("userName"), setMap.get("userPwd"));
- simEmailObject.setHostName(setMap.get("hostName"));
- simEmailObject.setFrom(setMap.get("from"));
- } catch (EmailException ex) {
- Logger.getLogger(EmailContext.class.getName()).log(Level.SEVERE, null, ex);
- JOptionPane.showMessageDialog(
- null, "提示", "发件人信息加载失败", JOptionPane.INFORMATION_MESSAGE);
- }
- /**
- * 设置收件人信息
- */
- for (int i = 0, j = contactsList.size(); i < j; i++) {
- try {
- simEmailObject.addTo(contactsList.get(i));
- } catch (EmailException ex) {
- Logger.getLogger(EmailContext.class.getName()).log(Level.SEVERE, null, ex);
- JOptionPane.showMessageDialog(
- null, "提示", "联系人信息加载失败", JOptionPane.INFORMATION_MESSAGE);
- }
- }
- /**
- * 设置邮件内容信息
- */
- try {
- simEmailObject.setSubject(contentsEmail.get("theme"));
- simEmailObject.setMsg(contentsEmail.get("contents"));
- } catch (EmailException ex) {
- Logger.getLogger(EmailContext.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
- }
抽象不是一蹴而就的,刚开始就没能高瞻远瞩的看到这一点,以致后面才有了一个反反复复的迭代的过程,自然也好受教训了,而且是历历在目的。
3.发送方法如此的消瘦
- /**
- * 发送电子邮件
- *
- * @param evt
- */
- private void sendMailActionPerformed(java.awt.event.ActionEvent evt) {
- List<String> contactsList = getContactsList();
- Map<String, String> setMap = getMailSettingInfor();
- Map<String, String> setContentsMap = getMailContents();
- EmailContext ect = new EmailContext(setMap, contactsList, setContentsMap, attactmentsFiles);
- String result = ect.sendEmail();
- statusInforLab.setText(result);
- }
在发送方法中基本上看不到判断策略的代码,普通的方法调用,这回算是回归本相了。
写到这,文字上的总结也应该告一段落。关于如何抽象,如何组织,如何设计,如何高瞻远瞩的看到所将要经历的过程,一大堆的疑问还待通过更多的眼见的,耳听的,手动的,试验过的经历一一解答。
本文出自 “野马红尘” 博客,谢绝转载!