DIY迷你邮件客户端开发手记(三)

简介:

      DIY迷你邮件客户端的开发结束了,现在完全可以Shift+Delete掉这个工程了。享受这个过程已经完整的进行完了,剩下的问题应该算是总结这个工程。

     在 DIY迷你邮件客户端开发手记(一)中已经很勇敢的面对了失败的开始,然后在不好的开端下进行一步一步的修正,过程很惨,结果呢?开始的激动全没有了,剩下最后这两篇文字和在一大堆代码中被狂砍剩下来的几十代码。

      在DIY迷你邮件客户端开发手记(二)总结和思考了关于“一”中提到的几个问题。生活和工作中没有如果,发生了就该面对,重读《编码匠艺》,消除不必要的如果,珍惜碎屑时间,换取和MM的共度的美好时光,苦逼真是自找的啦。

1. 关于测试和实验

     实验: 经常会面临一个问题就是要实现某一功能,但是有不确定能否一次性就能够实现,这时候就得停下脚步,做一些较为简单的例子,进行技术上的实验,通过的简单的实验可以节省时间,并且有利于技术的确认,增强开发信心。

    测试:测试应该是伴随整个开发过程的,而且非常有必要将测试深入,严格的渗透到我们的开发过程中去。每一个模块就要存在相关的测试代码,并且确保已经完成的部分能够直接作为成品集成到项目中。

   体会:保留测试代码有利于复查和实时测试

2.提取共同,抽象业务

        面向对象的圣经可是絮叨的像祥林嫂一样被念叨,然而不正真感受抽象的重要性,是很难懂得其中的智慧。

       PS:在起初设计这个邮件发送的时候同样使用了策略模式,可是最后发现不是这么回事,因为没一份邮件都有一个共同点,邮件服务器,用户名,密码,主题,联系人等。对于普通邮件和附件邮件的区别也仅仅在附件方面处理有所不同而已。

      抽象出了严重的问题,导致整个工作进展停滞不前,不停的改动,组织最后还是需要足够的魄力来个Shift+Delete结束过多的纠结,这样就有了后面的事了。学习了一下commons-email-1.x的实现思路,重新对发送邮件进行了包装,这样解决了不同类型邮件的发送问题,收件人电子邮件地址加载问题。

      编码:使用EmailContext类对其进行了相应的处理。

 
  1. public class EmailContext {  
  2.  
  3.     private Map<String, String> setMap = null;  
  4.     private List<String> contactsList = null;  
  5.     private Map<String, String> contentsEmail = null;  
  6.     private MultiPartEmail mutEmailObject = null;  
  7.     private SimpleEmail simEmailObject = null;  
  8.     private File[] attactFiles = null;  
  9.  
  10.     /**  
  11.      * 获取发送邮件实例对象  
  12.      *  
  13.      * @param setMap  
  14.      * @param contactsList  
  15.      * @param contentsEmail  
  16.      * @param attactFiles  
  17.      *  
  18.      */ 
  19.     public EmailContext(Map<String, String> setMap, List<String> contactsList, Map<String, String> contentsEmail, File[] attactFiles) {  
  20.         this.attactFiles = attactFiles;  
  21.         this.setMap = setMap;  
  22.         this.contentsEmail = contentsEmail;  
  23.         this.contactsList = contactsList;  
  24.         if (this.attactFiles != null) {  
  25.             mutEmailObject = new MultiPartEmail();  
  26.         }  
  27.         if (this.attactFiles == null) {  
  28.             simEmailObject = new SimpleEmail();  
  29.         }  
  30.     }  
  31.  
  32.     /**  
  33.      * 发送电子邮件  
  34.      *  
  35.      * @return String  
  36.      */ 
  37.     public String sendEmail() {  
  38.         String result = "发送失败";  
  39.         try {  
  40.             if (mutEmailObject != null) {  
  41.                 setMultiPartEmailMessage();  
  42.                 result = mutEmailObject.send();  
  43.             }  
  44.             if (simEmailObject != null) {  
  45.                 setSimpleEmailMessage();  
  46.                 result = simEmailObject.send();  
  47.             }  
  48.         } catch (EmailException ex) {  
  49.             Logger.getLogger(EmailContext.class.getName()).log(Level.SEVERE, null, ex);  
  50.             JOptionPane.showMessageDialog(null, result, "提示", JOptionPane.INFORMATION_MESSAGE);  
  51.         }  
  52.         if (!result.equals("发送失败")) {  
  53.             result = "发送成功";  
  54.         }  
  55.         return result;  
  56.     }  
  57.  
  58.     /**  
  59.      * 设置带附件发送邮件信息  
  60.      */ 
  61.     private void setMultiPartEmailMessage() {  
  62.         /**  
  63.          * 设置发件人信息  
  64.          */ 
  65.         try {  
  66.             mutEmailObject.setAuthentication(setMap.get("userName"), setMap.get("userPwd"));  
  67.             mutEmailObject.setHostName(setMap.get("hostName"));  
  68.             mutEmailObject.setFrom(setMap.get("from"));  
  69.         } catch (EmailException ex) {  
  70.             Logger.getLogger(EmailContext.class.getName()).log(Level.SEVERE, null, ex);  
  71.             JOptionPane.showMessageDialog(null"提示""发件人信息加载失败", JOptionPane.INFORMATION_MESSAGE);  
  72.         }  
  73.         /**  
  74.          * 设置收件人信息  
  75.          */ 
  76.         for (int i = 0, j = contactsList.size(); i < j; i++) {  
  77.             try {  
  78.                 mutEmailObject.addTo(contactsList.get(i));  
  79.             } catch (EmailException ex) {  
  80.                 Logger.getLogger(EmailContext.class.getName()).log(Level.SEVERE, null, ex);  
  81.                 JOptionPane.showMessageDialog(null"提示""联系人信息加载失败", JOptionPane.INFORMATION_MESSAGE);  
  82.             }  
  83.         }  
  84.         /**  
  85.          * 设置发送附件信息  
  86.          */ 
  87.         EmailAttachment attact = null;  
  88.         for (int i = 0, j = attactFiles.length; i < j; i++) {  
  89.             try {  
  90.                 attact = new EmailAttachment();  
  91.                 attact.setPath(attactFiles[i].getAbsolutePath());  
  92.                 mutEmailObject.attach(attact);  
  93.             } catch (EmailException ex) {  
  94.                 Logger.getLogger(EmailContext.class.getName()).log(Level.SEVERE, null, ex);  
  95.                 JOptionPane.showMessageDialog(null"提示""附件加载失败", JOptionPane.INFORMATION_MESSAGE);  
  96.             }  
  97.         }  
  98.  
  99.         /**  
  100.          * 设置邮件内容信息  
  101.          */ 
  102.         try {  
  103.             mutEmailObject.setSubject(contentsEmail.get("theme"));  
  104.             mutEmailObject.setMsg(contentsEmail.get("contents"));  
  105.         } catch (EmailException ex) {  
  106.             Logger.getLogger(EmailContext.class.getName()).log(Level.SEVERE, null, ex);  
  107.         }  
  108.     }  
  109.  
  110.     /**  
  111.      * 设置发送邮件信息  
  112.      */ 
  113.     private void setSimpleEmailMessage() {  
  114.         /**  
  115.          * 设置发件人信息  
  116.          */ 
  117.         try {  
  118.             simEmailObject.setAuthentication(setMap.get("userName"), setMap.get("userPwd"));  
  119.             simEmailObject.setHostName(setMap.get("hostName"));  
  120.             simEmailObject.setFrom(setMap.get("from"));  
  121.         } catch (EmailException ex) {  
  122.             Logger.getLogger(EmailContext.class.getName()).log(Level.SEVERE, null, ex);  
  123.             JOptionPane.showMessageDialog(  
  124.                     null"提示""发件人信息加载失败", JOptionPane.INFORMATION_MESSAGE);  
  125.         }  
  126.         /**  
  127.          * 设置收件人信息  
  128.          */ 
  129.         for (int i = 0, j = contactsList.size(); i < j; i++) {  
  130.             try {  
  131.                 simEmailObject.addTo(contactsList.get(i));  
  132.             } catch (EmailException ex) {  
  133.                 Logger.getLogger(EmailContext.class.getName()).log(Level.SEVERE, null, ex);  
  134.                 JOptionPane.showMessageDialog(  
  135.                         null"提示""联系人信息加载失败", JOptionPane.INFORMATION_MESSAGE);  
  136.             }  
  137.         }  
  138.         /**  
  139.          * 设置邮件内容信息  
  140.          */ 
  141.         try {  
  142.             simEmailObject.setSubject(contentsEmail.get("theme"));  
  143.             simEmailObject.setMsg(contentsEmail.get("contents"));  
  144.         } catch (EmailException ex) {  
  145.             Logger.getLogger(EmailContext.class.getName()).log(Level.SEVERE, null, ex);  
  146.         }  
  147.     }  
  148. }  

     抽象不是一蹴而就的,刚开始就没能高瞻远瞩的看到这一点,以致后面才有了一个反反复复的迭代的过程,自然也好受教训了,而且是历历在目的。

3.发送方法如此的消瘦

 

 
  1. /**  
  2.  * 发送电子邮件  
  3.  *  
  4.  * @param evt  
  5.  */ 
  6. private void sendMailActionPerformed(java.awt.event.ActionEvent evt) {                                           
  7.  
  8.     List<String> contactsList = getContactsList();  
  9.     Map<String, String> setMap = getMailSettingInfor();  
  10.     Map<String, String> setContentsMap = getMailContents();  
  11.     EmailContext ect = new EmailContext(setMap, contactsList, setContentsMap, attactmentsFiles);  
  12.     String result = ect.sendEmail();  
  13.     statusInforLab.setText(result);  

      在发送方法中基本上看不到判断策略的代码,普通的方法调用,这回算是回归本相了。

      写到这,文字上的总结也应该告一段落。关于如何抽象,如何组织,如何设计,如何高瞻远瞩的看到所将要经历的过程,一大堆的疑问还待通过更多的眼见的,耳听的,手动的,试验过的经历一一解答。

 



本文转自 secondriver 51CTO博客,原文链接:http://blog.51cto.com/aiilive/1063972,如需转载请自行联系原作者

相关文章
|
6月前
|
设计模式 缓存 前端开发
一款清新优雅的中后台模板,内置丰富可配置的主题(强烈推荐)
Soybean Admin 是一个基于 Vue3、Vite3、TypeScript、NaiveUI、Pinia 和 UnoCSS 的清新优雅的中后台模版,它使用了最新的前端技术栈,内置丰富的主题配置,有着极高的代码规范,基于 mock 实现的动态权限路由,开箱即用的中后台前端解决方案,也可用于学习参考。
|
4月前
微信小游戏制作工具中的分享功能怎么用?
微信小游戏制作工具中的分享功能怎么用?
30 0
|
监控 JavaScript 安全
一款web端的好用又好看的音乐、视频播放器-XGPlayer
视频播放器一直是Web端比较难整的功能,虽然已经有比较优秀的开源库。可以满足日常开发大部分的功能,但是在一些功能上还是不尽如人意。今天给大家介绍一款由西瓜团队开源的视频播放器。
一款web端的好用又好看的音乐、视频播放器-XGPlayer
|
监控 搜索推荐 C#
听音乐不过瘾?自制一个音乐播放器!【附带函数源码】
听音乐不过瘾?自制一个音乐播放器!【附带函数源码】
134 0
听音乐不过瘾?自制一个音乐播放器!【附带函数源码】
|
C++
Qt-网易云音乐界面实现-3 音乐名片模块的实现
Qt-网易云音乐界面实现-3 音乐名片模块的实现
124 0
Qt-网易云音乐界面实现-3 音乐名片模块的实现
|
测试技术
ATtiny85 制作迷你小游戏机
代码在 https://pan.baidu.com/s/1n4KhEdyiCdrbhwEAEWyNDg 提取码: k6zk 1.准备 原件 说明 Attiny85 1个 128x64 OLED IIC 1个...
4163 0
|
Android开发 UED iOS开发
安卓设计师不容错过的15款实用UI界面设计工具
最近刮起了一股“养蛙儿子”的风潮。独特的UI设计、萌萌的画风和简洁的用户体验吸引了大批的用户。在不少人直呼“哇,我的蛙儿子好可爱,好萌”的背后,我们可以看到一个高质量的UI设计对于提高应用下载量有着非常重要的作用。
2390 0