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

Stella981
• 阅读 452

     DIY迷你邮件客户端的开发算是告一段落,能够从中获取的东西需要往后实践中去感受和践行了。面对开始出现的问题,没能处理好,只有在整个过程来处理和消化掉可能带来的更多问题。

    思考DIY迷你客户端开发手记(一)中的5中问题才是清除掉乱七八糟的工程之后的价值了。

  1.业务策略编程

       在整个应用中最核心的问题是:通过选择收件人的邮件地址的源文件,加载到收件人的集合中,进而发送相应的邮件。

      处理这个问题自然想到了策略模式。

     先定义一个接口,声明了子类需要实现的方法,然后通过不同的需求来实现其中的功能。

     编码-0:定义了解析文件中的联系人邮件地址的策略接口

   public interface AnalysisStrategy {  
  
 
  
 
  
 
   
         
  
 
  
 
  
 
   
       /**  
  
 
  
 
  
 
   
        *   
  
 
  
 
  
 
   
        * 解析联系人数据源  
  
 
  
 
  
 
   
        *   
  
 
  
 
  
 
   
        * @return list  
  
 
  
 
  
 
   
        */ 
  
 
  
 
  
 
   
       public List<String> analysisSrc();  
  
 
  
 
  
 
   
         
  
 
  
 
  
 
   
   } 
 

 

 

  
  

     编码-1:主要的两种模式是,解析Excel文件和XML文件

   public class ExcelContacts implements AnalysisStrategy {  
  
 
  
 
  
 
   
    
  
 
  
 
  
 
   
       private File excelFile;  
  
 
  
 
  
 
   
    
  
 
  
 
  
 
   
       
  
 
  
 
  
 
   
       public ExcelContacts(File f) {  
  
 
  
 
  
 
   
           this.excelFile = f;  
  
 
  
 
  
 
   
       }  
  
 
  
 
  
 
   
    
  
 
  
 
  
 
   
       /**  
  
 
  
 
  
 
   
        * 联系人Excel表  
  
 
  
 
  
 
   
        *  
  
 
  
 
  
 
   
        * @help 参见规定的Excel格式  
  
 
  
 
  
 
   
        *  
  
 
  
 
  
 
   
        * @return list  
  
 
  
 
  
 
   
        */ 
  
 
  
 
  
 
   
       @Override 
  
 
  
 
  
 
   
       public List<String> analysisSrc() {  
  
 
  
 
  
 
   
           Workbook wb = null;  
  
 
  
 
  
 
   
           List<String> contactsList = null;  
  
 
  
 
  
 
   
           try {  
  
 
  
 
  
 
   
               wb = Workbook.getWorkbook(excelFile);  
  
 
  
 
  
 
   
               Sheet[] sheets = wb.getSheets();  
  
 
  
 
  
 
   
               contactsList = new ArrayList<String>();  
  
 
  
 
  
 
   
               for (int i = 0, j = sheets.length; i < j; i++) {  
  
 
  
 
  
 
   
                   Cell[] cells = sheets[i].getColumn(2);  
  
 
  
 
  
 
   
                   for (int row = 1, rows = cells.length; row < rows; row++) {  
  
 
  
 
  
 
   
                       String str=cells[row].getContents().trim();  
  
 
  
 
  
 
   
                       if(MiniMailTool.checkEmail(str)){  
  
 
  
 
  
 
   
                           contactsList.add(str);  
  
 
  
 
  
 
   
                       }  
  
 
  
 
  
 
   
                   }  
  
 
  
 
  
 
   
               }  
  
 
  
 
  
 
   
           } catch (IOException ex) {  
  
 
  
 
  
 
   
               Logger.getLogger(ExcelContacts.class.getName()).log(Level.SEVERE, null, ex);  
  
 
  
 
  
 
   
           } catch (BiffException ex) {  
  
 
  
 
  
 
   
               Logger.getLogger(ExcelContacts.class.getName()).log(Level.SEVERE, null, ex);  
  
 
  
 
  
 
   
           }  
  
 
  
 
  
 
   
           return contactsList;  
  
 
  
 
  
 
   
       }  
  
 
  
 
  
 
   
   }  
  
 
  
 
  
 
   
   //-----------------------------------------------------//  
  
 
  
 
  
 
   
    
  
 
  
 
  
 
   
   public class XMLContacts implements AnalysisStrategy {  
  
 
  
 
  
 
   
    
  
 
  
 
  
 
   
       private File xmlFile;  
  
 
  
 
  
 
   
    
  
 
  
 
  
 
   
       public XMLContacts(File f) {  
  
 
  
 
  
 
   
           this.xmlFile=f;  
  
 
  
 
  
 
   
       }  
  
 
  
 
  
 
   
    
  
 
  
 
  
 
   
       /**  
  
 
  
 
  
 
   
        * 联系人XML表   
  
 
  
 
  
 
   
        *   
  
 
  
 
  
 
   
        * @help 参见规定的XML格式  
  
 
  
 
  
 
   
        *  
  
 
  
 
  
 
   
        * @param xmlFile  
  
 
  
 
  
 
   
        * @return list  
  
 
  
 
  
 
   
        */ 
  
 
  
 
  
 
   
       @Override 
  
 
  
 
  
 
   
       public List<String> analysisSrc() {  
  
 
  
 
  
 
   
           List<String> contactsList=null;  
  
 
  
 
  
 
   
           try {  
  
 
  
 
  
 
   
               SAXBuilder sb =new SAXBuilder();  
  
 
  
 
  
 
   
               Document doc=sb.build(xmlFile);  
  
 
  
 
  
 
   
               Element root=doc.getRootElement();  
  
 
  
 
  
 
   
               List<Element> userList=root.getChildren("user");  
  
 
  
 
  
 
   
               contactsList=new ArrayList<String>();  
  
 
  
 
  
 
   
               for(int i=0, j=userList.size(); i<j; i++){  
  
 
  
 
  
 
   
                   Element children=userList.get(i);  
  
 
  
 
  
 
   
                   String str=children.getChildText("email").trim();  
  
 
  
 
  
 
   
                   if(MiniMailTool.checkEmail(str)){  
  
 
  
 
  
 
   
                       contactsList.add(str);  
  
 
  
 
  
 
   
                   }  
  
 
  
 
  
 
   
               }  
  
 
  
 
  
 
   
           } catch (JDOMException ex) {  
  
 
  
 
  
 
   
               Logger.getLogger(XMLContacts.class.getName()).log(Level.SEVERE, null, ex);  
  
 
  
 
  
 
   
           } catch (IOException ex) {  
  
 
  
 
  
 
   
               Logger.getLogger(XMLContacts.class.getName()).log(Level.SEVERE, null, ex);  
  
 
  
 
  
 
   
           }  
  
 
  
 
  
 
   
           return contactsList;  
  
 
  
 
  
 
   
       }  
  
 
  
 
  
 
   
   } 
 

 

 

  
  

    通过这样的方式就可以将不同的文件的解析联系人的过程封装掉,对于调用者来讲是相同的,只需要面向接口编程就可以了。

   这里给出源文件的格式:

   EXCEL表的格式

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

   XML格式:

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

     这里的格式可以按照已经约定的方式书写,当然亦可以自定义格式,这样就应该编写实现

AnalysisStrategy(联系人解析)接口。

2.处理一些关于字符串,邮件地址验证,获取收件人地址信息

这样的问题一般在编程开始的时候会有所考虑,倒是带来的后续问题不大,如何有效的编写更加通用的代码,才是问题的关键。

这里有个关于工具类的命名问题,比如:Utils,Tools,Helper等类的命名都是非常不可取的方式,命名要简明思议,并且能够传单一定的信息,像这个工具类处理哪方面的问题,都应该能够很好的放映出来。

工具类有可能涉及到:字符串处理方面;文件解析,文件过滤方面;图形用户界面编程中的组件信息处理方面;特定的多出使用的方法,变量等;类的构造和管理等方面。

这个应用程序设计的相关方法不是很多,较好的处理掉了。

编码-2:邮件客户端程序的工具类

   /**  
  
 
  
 
  
 
   
    *  
  
 
  
 
  
 
   
    * 邮件客户端程序工具类  
  
 
  
 
  
 
   
    *  
  
 
  
 
  
 
   
    * @author aiilive   
  
 
  
 
  
 
   
    */ 
  
 
  
 
  
 
   
   public final class MiniMailTool {  
  
 
  
 
  
 
   
    
  
 
  
 
  
 
   
       /**  
  
 
  
 
  
 
   
        * 获取框架在Windows中显示的中心点  
  
 
  
 
  
 
   
        *  
  
 
  
 
  
 
   
        * @param jf  
  
 
  
 
  
 
   
        * @return 中心点  
  
 
  
 
  
 
   
        */ 
  
 
  
 
  
 
   
       public static Point getCenter(JFrame jf) {  
  
 
  
 
  
 
   
           Point p = new Point();  
  
 
  
 
  
 
   
           Dimension dim = jf.getSize();  
  
 
  
 
  
 
   
           int width = dim.width;  
  
 
  
 
  
 
   
           int height = dim.height;  
  
 
  
 
  
 
   
           Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();  
  
 
  
 
  
 
   
           p.setLocation((screenSize.width - width) / 2, ((screenSize.height - height) / 2));  
  
 
  
 
  
 
   
           return p;  
  
 
  
 
  
 
   
       }  
  
 
  
 
  
 
   
    
  
 
  
 
  
 
   
       /**  
  
 
  
 
  
 
   
        * 通过收件人信息获取收件人  
  
 
  
 
  
 
   
        *  
  
 
  
 
  
 
   
        * @param contactsString  
  
 
  
 
  
 
   
        * @return List  
  
 
  
 
  
 
   
        */ 
  
 
  
 
  
 
   
       public static List getToContacts(String contactsText) {  
  
 
  
 
  
 
   
          String[] contacts = contactsText.split(";");   
  
 
  
 
  
 
   
           return Arrays.asList(contacts);  
  
 
  
 
  
 
   
       }  
  
 
  
 
  
 
   
    
  
 
  
 
  
 
   
       /**  
  
 
  
 
  
 
   
        * 验证输入的联系人的电子邮箱的有效性  
  
 
  
 
  
 
   
        *   
  
 
  
 
  
 
   
        * @param contactsText  
  
 
  
 
  
 
   
        * @return bo  
  
 
  
 
  
 
   
        */ 
  
 
  
 
  
 
   
       public static boolean checkContacts(String contactsText){  
  
 
  
 
  
 
   
           String[] contacts = contactsText.split(";");  
  
 
  
 
  
 
   
           boolean bo=true;  
  
 
  
 
  
 
   
           for (int i = 0; i < contacts.length; i++) {  
  
 
  
 
  
 
   
               contacts[i] = contacts[i].trim();  
  
 
  
 
  
 
   
               if(!checkEmail(contacts[i])){  
  
 
  
 
  
 
   
                   bo=false;  
  
 
  
 
  
 
   
                   break;  
  
 
  
 
  
 
   
               }  
  
 
  
 
  
 
   
           }  
  
 
  
 
  
 
   
           return bo;  
  
 
  
 
  
 
   
       }  
  
 
  
 
  
 
   
         
  
 
  
 
  
 
   
       /**  
  
 
  
 
  
 
   
        * 中文字符转换  
  
 
  
 
  
 
   
        *  
  
 
  
 
  
 
   
        * @param str  
  
 
  
 
  
 
   
        * @return strEncode  
  
 
  
 
  
 
   
        */ 
  
 
  
 
  
 
   
       public static String chineseEncode(String str) {  
  
 
  
 
  
 
   
           String strEncode = str;  
  
 
  
 
  
 
   
           try {  
  
 
  
 
  
 
   
               byte[] bts = str.getBytes("ISO-8859-1");  
  
 
  
 
  
 
   
               strEncode = new String(bts, "GB2312");  
  
 
  
 
  
 
   
           } catch (UnsupportedEncodingException ex) {  
  
 
  
 
  
 
   
               Logger.getLogger(MiniMailTool.class.getName()).log(Level.SEVERE, null, ex);  
  
 
  
 
  
 
   
           }  
  
 
  
 
  
 
   
           return strEncode;  
  
 
  
 
  
 
   
       }  
  
 
  
 
  
 
   
    
  
 
  
 
  
 
   
       /**  
  
 
  
 
  
 
   
        * 将字符数组char [] 转化为字符串String  
  
 
  
 
  
 
   
        *  
  
 
  
 
  
 
   
        * @param ch []  
  
 
  
 
  
 
   
        * @return String  
  
 
  
 
  
 
   
        */ 
  
 
  
 
  
 
   
       public static String arrayToString(char[] ch) {  
  
 
  
 
  
 
   
           if (ch == null) {  
  
 
  
 
  
 
   
               return "null";  
  
 
  
 
  
 
   
           }  
  
 
  
 
  
 
   
           StringBuilder b = new StringBuilder();  
  
 
  
 
  
 
   
           for (int i = 0; i < ch.length; i++) {  
  
 
  
 
  
 
   
               b.append(ch[i]);  
  
 
  
 
  
 
   
           }  
  
 
  
 
  
 
   
           return b.toString();  
  
 
  
 
  
 
   
       }  
  
 
  
 
  
 
   
    
  
 
  
 
  
 
   
       /**  
  
 
  
 
  
 
   
        * 验证电子邮件地址是否有效  
  
 
  
 
  
 
   
        *  
  
 
  
 
  
 
   
        * @param email 电子邮件地址字符串  
  
 
  
 
  
 
   
        * @return 布尔值  
  
 
  
 
  
 
   
        */ 
  
 
  
 
  
 
   
       public static boolean checkEmail(String email) {  
  
 
  
 
  
 
   
           Pattern pattern=Pattern.compile("\\w+@(\\w+.)+[a-z]{2,3}");  
  
 
  
 
  
 
   
           Matcher matcher=pattern.matcher(email);  
  
 
  
 
  
 
   
           return matcher.matches();  
  
 
  
 
  
 
   
       }  
  
 
  
 
  
 
   
   } 
 

 

 

  
  

上面的代码涉及到了用户界面组件的工具类方法,字符串处理,常用的验证等。对于一个较大的工程,或者是涉及相关的操作非常多和复杂的时候,就得考虑方法的组织,重构,提取,建立更好的类的层次关系这样才符合面向对象编程基本思想,才能够获得可以水平和垂直扩展的机会。同时使得代码的耦合度降到最低,想要达到如此美好的境况,又得回到设计和组织方面去。

3.用户界面的布局,各个组件在特定时间的状态

    正因为有用户界面,所以考虑各组件之间的组织关系,程序运行是组件的状态。活动图虽然集中注意力的面向的是活动参与者,对于桌面应用程序而言,每一个组件正可以看作是活动的参与者,因此正确对待组件状态,就可以呈现一个真实的活动状态。

    比如:在没有进行邮件信息检查时,发送按钮是禁用的;为发送邮件时,状态信息显示填写发件信息,发送完成时发送完成或者发送失败;验证收件人的电子邮件信息时;不符合格式的地址,显示相应的提示信息等等,这样都源于我们对客观的事物和感知,也是对我们的用户交互,人性化设计的要求。

本文出自 “野马红尘” 博客,谢绝转载!

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Stella981 Stella981
2年前
Python之time模块的时间戳、时间字符串格式化与转换
Python处理时间和时间戳的内置模块就有time,和datetime两个,本文先说time模块。关于时间戳的几个概念时间戳,根据1970年1月1日00:00:00开始按秒计算的偏移量。时间元组(struct_time),包含9个元素。 time.struct_time(tm_y
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这