DIY迷你郵件客戶端的開發算是告一段落,可以從中獲取的東西須要日後實踐中去感覺和踐行了。面對開始出現的問題,沒能處理好,只有在整個過程來處理和消化掉可能帶來的更多問題。編程
思考DIY迷你客戶端開發手記(一)中的5中問題纔是清除掉亂七八糟的工程以後的價值了。數組
1.業務策略編程app
在整個應用中最核心的問題是:經過選擇收件人的郵件地址的源文件,加載到收件人的集合中,進而發送相應的郵件。框架
處理這個問題天然想到了策略模式。ide
先定義一個接口,聲明瞭子類須要實現的方法,而後經過不一樣的需求來實現其中的功能。工具
編碼-0:定義瞭解析文件中的聯繫人郵件地址的策略接口佈局
- public interface AnalysisStrategy {
- /**
- *
- * 解析聯繫人數據源
- *
- * @return list
- */
- public List<String> analysi***c();
- }
編碼-1:主要的兩種模式是,解析Excel文件和XML文件ui
- public class ExcelContacts implements AnalysisStrategy {
- private File excelFile;
- public ExcelContacts(File f) {
- this.excelFile = f;
- }
- /**
- * 聯繫人Excel表
- *
- * @help 參見規定的Excel格式
- *
- * @return list
- */
- @Override
- public List<String> analysi***c() {
- 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> analysi***c() {
- 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;
- }
- }
經過這樣的方式就能夠將不一樣的文件的解析聯繫人的過程封裝掉,對於調用者來說是相同的,只須要面向接口編程就能夠了。this
這裏給出源文件的格式:編碼
EXCEL表的格式
XML格式:
這裏的格式能夠按照已經約定的方式書寫,固然亦能夠自定義格式,這樣就應該編寫實現
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.用戶界面的佈局,各個組件在特定時間的狀態
正由於有用戶界面,因此考慮各組件之間的組織關係,程序運行是組件的狀態。活動圖雖然集中注意力的面向的是活動參與者,對於桌面應用程序而言,每個組件正能夠看做是活動的參與者,所以正確對待組件狀態,就能夠呈現一個真實的活動狀態。
好比:在沒有進行郵件信息檢查時,發送按鈕是禁用的;爲發送郵件時,狀態信息顯示填寫發件信息,發送完成時發送完成或者發送失敗;驗證收件人的電子郵件信息時;不符合格式的地址,顯示相應的提示信息等等,這樣都源於咱們對客觀的事物和感知,也是對咱們的用戶交互,人性化設計的要求。