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

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

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

  1.业务策略编程

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

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

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

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

1 public interface AnalysisStrategy {   2 3 4 5 6 7 8 9        10 11 12 13 14 15 16 17     /**   18 19 20 21 22 23 24 25      *    26 27 28 29 30 31 32 33      * 解析联系人数据源   34 35 36 37 38 39 40 41      *    42 43 44 45 46 47 48 49      * @return list   50 51 52 53 54 55 56 57      */  58 59 60 61 62 63 64 65     public List<String> analysisSrc();   66 67 68 69 70 71 72 73        74 75 76 77 78 79 80 81 }  82 83 84 85 86 87 88 89

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

1 public class ExcelContacts implements AnalysisStrategy {   2 3 4 5 6 7 8 9   10 11 12 13 14 15 16 17     private File excelFile;   18 19 20 21 22 23 24 25   26 27 28 29 30 31 32 33      34 35 36 37 38 39 40 41     public ExcelContacts(File f) {   42 43 44 45 46 47 48 49         this.excelFile = f;   50 51 52 53 54 55 56 57     }   58 59 60 61 62 63 64 65   66 67 68 69 70 71 72 73     /**   74 75 76 77 78 79 80 81      * 联系人Excel表   82 83 84 85 86 87 88 89      *   90 91 92 93 94 95 96 97      * @help 参见规定的Excel格式   98 99 100 101 102 103 104 105      *   106 107 108 109 110 111 112 113      * @return list   114 115 116 117 118 119 120 121      */  122 123 124 125 126 127 128 129     @Override  130 131 132 133 134 135 136 137     public List<String> analysisSrc() {   138 139 140 141 142 143 144 145         Workbook wb = null;   146 147 148 149 150 151 152 153         List<String> contactsList = null;   154 155 156 157 158 159 160 161         try {   162 163 164 165 166 167 168 169             wb = Workbook.getWorkbook(excelFile);   170 171 172 173 174 175 176 177             Sheet[] sheets = wb.getSheets();   178 179 180 181 182 183 184 185             contactsList = new ArrayList<String>();   186 187 188 189 190 191 192 193             for (int i = 0, j = sheets.length; i < j; i++) {   194 195 196 197 198 199 200 201                 Cell[] cells = sheets[i].getColumn(2);   202 203 204 205 206 207 208 209                 for (int row = 1, rows = cells.length; row < rows; row++) {   210 211 212 213 214 215 216 217                     String str=cells[row].getContents().trim();   218 219 220 221 222 223 224 225                     if(MiniMailTool.checkEmail(str)){   226 227 228 229 230 231 232 233                         contactsList.add(str);   234 235 236 237 238 239 240 241                     }   242 243 244 245 246 247 248 249                 }   250 251 252 253 254 255 256 257             }   258 259 260 261 262 263 264 265         } catch (IOException ex) {   266 267 268 269 270 271 272 273             Logger.getLogger(ExcelContacts.class.getName()).log(Level.SEVERE, null, ex);   274 275 276 277 278 279 280 281         } catch (BiffException ex) {   282 283 284 285 286 287 288 289             Logger.getLogger(ExcelContacts.class.getName()).log(Level.SEVERE, null, ex);   290 291 292 293 294 295 296 297         }   298 299 300 301 302 303 304 305         return contactsList;   306 307 308 309 310 311 312 313     }   314 315 316 317 318 319 320 321 }   322 323 324 325 326 327 328 329 //-----------------------------------------------------//   330 331 332 333 334 335 336 337   338 339 340 341 342 343 344 345 public class XMLContacts implements AnalysisStrategy {   346 347 348 349 350 351 352 353   354 355 356 357 358 359 360 361     private File xmlFile;   362 363 364 365 366 367 368 369   370 371 372 373 374 375 376 377     public XMLContacts(File f) {   378 379 380 381 382 383 384 385         this.xmlFile=f;   386 387 388 389 390 391 392 393     }   394 395 396 397 398 399 400 401   402 403 404 405 406 407 408 409     /**   410 411 412 413 414 415 416 417      * 联系人XML表    418 419 420 421 422 423 424 425      *    426 427 428 429 430 431 432 433      * @help 参见规定的XML格式   434 435 436 437 438 439 440 441      *   442 443 444 445 446 447 448 449      * @param xmlFile   450 451 452 453 454 455 456 457      * @return list   458 459 460 461 462 463 464 465      */  466 467 468 469 470 471 472 473     @Override  474 475 476 477 478 479 480 481     public List<String> analysisSrc() {   482 483 484 485 486 487 488 489         List<String> contactsList=null;   490 491 492 493 494 495 496 497         try {   498 499 500 501 502 503 504 505             SAXBuilder sb =new SAXBuilder();   506 507 508 509 510 511 512 513             Document doc=sb.build(xmlFile);   514 515 516 517 518 519 520 521             Element root=doc.getRootElement();   522 523 524 525 526 527 528 529             List<Element> userList=root.getChildren("user");   530 531 532 533 534 535 536 537             contactsList=new ArrayList<String>();   538 539 540 541 542 543 544 545             for(int i=0, j=userList.size(); i<j; i++){   546 547 548 549 550 551 552 553                 Element children=userList.get(i);   554 555 556 557 558 559 560 561                 String str=children.getChildText("email").trim();   562 563 564 565 566 567 568 569                 if(MiniMailTool.checkEmail(str)){   570 571 572 573 574 575 576 577                     contactsList.add(str);   578 579 580 581 582 583 584 585                 }   586 587 588 589 590 591 592 593             }   594 595 596 597 598 599 600 601         } catch (JDOMException ex) {   602 603 604 605 606 607 608 609             Logger.getLogger(XMLContacts.class.getName()).log(Level.SEVERE, null, ex);   610 611 612 613 614 615 616 617         } catch (IOException ex) {   618 619 620 621 622 623 624 625             Logger.getLogger(XMLContacts.class.getName()).log(Level.SEVERE, null, ex);   626 627 628 629 630 631 632 633         }   634 635 636 637 638 639 640 641         return contactsList;   642 643 644 645 646 647 648 649     }   650 651 652 653 654 655 656 657 }  658 659 660 661 662 663 664 665

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

   这里给出源文件的格式:

   EXCEL表的格式

 

   XML格式:

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

**AnalysisStrategy(联系人解析)**接口。

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

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

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

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

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

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

1 /**   2 3 4 5 6 7 8 9  *   10 11 12 13 14 15 16 17  * 邮件客户端程序工具类   18 19 20 21 22 23 24 25  *   26 27 28 29 30 31 32 33  * @author aiilive    34 35 36 37 38 39 40 41  */  42 43 44 45 46 47 48 49 public final class MiniMailTool {   50 51 52 53 54 55 56 57   58 59 60 61 62 63 64 65     /**   66 67 68 69 70 71 72 73      * 获取框架在Windows中显示的中心点   74 75 76 77 78 79 80 81      *   82 83 84 85 86 87 88 89      * @param jf   90 91 92 93 94 95 96 97      * @return 中心点   98 99 100 101 102 103 104 105      */  106 107 108 109 110 111 112 113     public static Point getCenter(JFrame jf) {   114 115 116 117 118 119 120 121         Point p = new Point();   122 123 124 125 126 127 128 129         Dimension dim = jf.getSize();   130 131 132 133 134 135 136 137         int width = dim.width;   138 139 140 141 142 143 144 145         int height = dim.height;   146 147 148 149 150 151 152 153         Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();   154 155 156 157 158 159 160 161         p.setLocation((screenSize.width - width) / 2, ((screenSize.height - height) / 2));   162 163 164 165 166 167 168 169         return p;   170 171 172 173 174 175 176 177     }   178 179 180 181 182 183 184 185   186 187 188 189 190 191 192 193     /**   194 195 196 197 198 199 200 201      * 通过收件人信息获取收件人   202 203 204 205 206 207 208 209      *   210 211 212 213 214 215 216 217      * @param contactsString   218 219 220 221 222 223 224 225      * @return List   226 227 228 229 230 231 232 233      */  234 235 236 237 238 239 240 241     public static List getToContacts(String contactsText) {   242 243 244 245 246 247 248 249        String[] contacts = contactsText.split(";");    250 251 252 253 254 255 256 257         return Arrays.asList(contacts);   258 259 260 261 262 263 264 265     }   266 267 268 269 270 271 272 273   274 275 276 277 278 279 280 281     /**   282 283 284 285 286 287 288 289      * 验证输入的联系人的电子邮箱的有效性   290 291 292 293 294 295 296 297      *    298 299 300 301 302 303 304 305      * @param contactsText   306 307 308 309 310 311 312 313      * @return bo   314 315 316 317 318 319 320 321      */  322 323 324 325 326 327 328 329     public static boolean checkContacts(String contactsText){   330 331 332 333 334 335 336 337         String[] contacts = contactsText.split(";");   338 339 340 341 342 343 344 345         boolean bo=true;   346 347 348 349 350 351 352 353         for (int i = 0; i < contacts.length; i++) {   354 355 356 357 358 359 360 361             contacts[i] = contacts[i].trim();   362 363 364 365 366 367 368 369             if(!checkEmail(contacts[i])){   370 371 372 373 374 375 376 377                 bo=false;   378 379 380 381 382 383 384 385                 break;   386 387 388 389 390 391 392 393             }   394 395 396 397 398 399 400 401         }   402 403 404 405 406 407 408 409         return bo;   410 411 412 413 414 415 416 417     }   418 419 420 421 422 423 424 425        426 427 428 429 430 431 432 433     /**   434 435 436 437 438 439 440 441      * 中文字符转换   442 443 444 445 446 447 448 449      *   450 451 452 453 454 455 456 457      * @param str   458 459 460 461 462 463 464 465      * @return strEncode   466 467 468 469 470 471 472 473      */  474 475 476 477 478 479 480 481     public static String chineseEncode(String str) {   482 483 484 485 486 487 488 489         String strEncode = str;   490 491 492 493 494 495 496 497         try {   498 499 500 501 502 503 504 505             byte[] bts = str.getBytes("ISO-8859-1");   506 507 508 509 510 511 512 513             strEncode = new String(bts, "GB2312");   514 515 516 517 518 519 520 521         } catch (UnsupportedEncodingException ex) {   522 523 524 525 526 527 528 529             Logger.getLogger(MiniMailTool.class.getName()).log(Level.SEVERE, null, ex);   530 531 532 533 534 535 536 537         }   538 539 540 541 542 543 544 545         return strEncode;   546 547 548 549 550 551 552 553     }   554 555 556 557 558 559 560 561   562 563 564 565 566 567 568 569     /**   570 571 572 573 574 575 576 577      * 将字符数组char [] 转化为字符串String   578 579 580 581 582 583 584 585      *   586 587 588 589 590 591 592 593      * @param ch []   594 595 596 597 598 599 600 601      * @return String   602 603 604 605 606 607 608 609      */  610 611 612 613 614 615 616 617     public static String arrayToString(char[] ch) {   618 619 620 621 622 623 624 625         if (ch == null) {   626 627 628 629 630 631 632 633             return "null";   634 635 636 637 638 639 640 641         }   642 643 644 645 646 647 648 649         StringBuilder b = new StringBuilder();   650 651 652 653 654 655 656 657         for (int i = 0; i < ch.length; i++) {   658 659 660 661 662 663 664 665             b.append(ch[i]);   666 667 668 669 670 671 672 673         }   674 675 676 677 678 679 680 681         return b.toString();   682 683 684 685 686 687 688 689     }   690 691 692 693 694 695 696 697   698 699 700 701 702 703 704 705     /**   706 707 708 709 710 711 712 713      * 验证电子邮件地址是否有效   714 715 716 717 718 719 720 721      *   722 723 724 725 726 727 728 729      * @param email 电子邮件地址字符串   730 731 732 733 734 735 736 737      * @return 布尔值   738 739 740 741 742 743 744 745      */  746 747 748 749 750 751 752 753     public static boolean checkEmail(String email) {   754 755 756 757 758 759 760 761         Pattern pattern=Pattern.compile("\\w+@(\\w+.)+[a-z]{2,3}");   762 763 764 765 766 767 768 769         Matcher matcher=pattern.matcher(email);   770 771 772 773 774 775 776 777         return matcher.matches();   778 779 780 781 782 783 784 785     }   786 787 788 789 790 791 792 793 }  794 795 796 797 798 799 800 801

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

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

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

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

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

点赞
收藏

评论区

加载中...

相关推荐

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

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )