• 重构了XmlDownloader类


    用了建造者模式。

    在公交车上考虑了两天,在脑子里大概画了个雏形,然后今晚解决了一些细节上的问题。

    不废话,发代码:

      1 package com.mlxy.xml;
      2 
      3 import java.io.BufferedReader;
      4 import java.io.BufferedWriter;
      5 import java.io.File;
      6 import java.io.FileOutputStream;
      7 import java.io.InputStream;
      8 import java.io.InputStreamReader;
      9 import java.io.OutputStreamWriter;
     10 import java.net.MalformedURLException;
     11 import java.net.URL;
     12 
     13 import android.content.Context;
     14 import android.os.Environment;
     15 
     16 import com.mlxy.util.CharacterProcesser;
     17 
     18 /**
     19  * Xml文件下载器,重构完成。
     20  * 
     21  * @author mlxy
     22  * @version 1.1
     23  * */
     24 public class XmlDownloader {
     25     private Context parent;
     26     
     27     private String cityName = "南昌";
     28     private String city = CharacterProcesser.encodeByGB2312(cityName);
     29     private String password = "DJOYnieT8234jlsK";
     30     private int day = 0;
     31     private String link = "http://php.weather.sina.com.cn/xml.php?city=" + city
     32             + "&password=" + password + "&day=" + day;
     33     
     34     /** 私有构造方法,避免被外部实例化。*/
     35     private XmlDownloader() {
     36     }
     37     
     38     /** 根据给定的链接下载对应的xml文件。
     39      * 
     40      * @param link API的链接,需要标明网络协议。*/
     41     private void downloadXml(String link) {
     42         // 用链接字符串new出URL对象
     43         URL url = null;
     44         try {
     45             url = new URL(link);
     46         } catch (MalformedURLException e) {
     47             e.printStackTrace();
     48         }
     49 
     50         // 获取外部存储路径并创建文件对象。
     51         File externalDirectory = Environment.getExternalStorageDirectory();
     52         String fileName = "xml_resource.xml";
     53         File file = new File(externalDirectory, fileName);
     54 
     55         // 写文件。
     56         
     57         // 初始化io流。
     58         InputStream in = null;
     59         BufferedReader reader = null;
     60         FileOutputStream out = null;
     61         BufferedWriter writer = null;
     62         
     63         try {
     64             
     65             // 建立连接并给io流赋值。
     66             in = (InputStream) url.getContent();
     67             reader = new BufferedReader(new InputStreamReader(in, "iso-8859-1"));
     68             out = this.parent.openFileOutput(file.getName(), Context.MODE_PRIVATE);
     69             writer = new BufferedWriter(new OutputStreamWriter(out, "iso-8859-1"));
     70             
     71             // 读一行写一行,然后另起一行。
     72             String line = null;
     73             while ((line = reader.readLine()) != null) {
     74                 writer.write(line);
     75                 writer.newLine();
     76             }
     77             
     78         } catch (Exception e) {
     79             e.printStackTrace();
     80         } finally {
     81             try {
     82                 // 释放资源
     83                 writer.flush();
     84                 writer.close();
     85                 out.close();
     86                 reader.close();
     87                 in.close();
     88             } catch (Exception e2) {
     89                 e2.printStackTrace();
     90             }
     91         }
     92     }
     93     
     94     private void setParent(Context parent) {
     95         this.parent = parent;
     96     }
     97     
     98     private void setCity(String cityName) {
     99         this.cityName = cityName;
    100     }
    101     
    102     private void setPassword(String password) {
    103         this.password = password;
    104     }
    105     
    106     private void setDay(int day) {
    107         this.day = day;
    108     }
    109     
    110     private String getLink() {
    111         return this.link;
    112     }
    113     
    114     public static class Builder {
    115         /** 储存好的一个实例,留待建造完毕后返回。*/
    116         private XmlDownloader instance = new XmlDownloader();
    117         
    118         /** 构造函数,需要输入启动此构造器的上下文视图作为参数。*/
    119         public Builder(Context parent) {
    120             instance.setParent(parent);
    121         }
    122         
    123         /** 设置城市名。</br>
    124          * 默认值为<b>南昌</b>。
    125          * 
    126          * @param cityName 城市名
    127          * @return 构造器本身
    128          */
    129         public Builder setCity(String cityName) {
    130             instance.setCity(cityName);
    131             return this;
    132         }
    133         
    134         /** 设置密码。</br>
    135          * 默认值为<b>DJOYnieT8234jlsK</b>。
    136          * 
    137          * @param password API密码
    138          * @return 构造器本身
    139          */
    140         public Builder setPassword(String password) {
    141             instance.setPassword(password);
    142             return this;
    143         }
    144         
    145         /** 设置日期。</br>
    146          * 默认值为<b>0</b>,也即是<b>今天</b>。</br>
    147          * 以此类推。
    148          * 
    149          * @param day 日子,0为当天,范围在0-4
    150          * @return 构造器本身
    151          */
    152         public Builder setDay(int day) {
    153             instance.setDay(day);
    154             return this;
    155         }
    156         
    157         /** 用已经设置好的或默认的参数下载XML文件。*/
    158         public void download() {
    159             String link = instance.getLink();
    160             instance.downloadXml(link);
    161         }
    162     }
    163 }
    需要结合前面几篇博文看

    场景类则这么调用:

     构建Xml下载器并下载Xml文件。
    new XmlDownloader.Builder(MainActivity.this)
            .setCity("南昌")
            .setPassword("DJOYnieT8234jlsK")
            .setDay(0)
            .download();

    具体实现方式参考了安卓的Toast和Dialog等几个类。

    纠结了一天要不要给建造者提供默认值,就是说在用户没有自己设定参数的情况下是直接返回null还是用默认值来处理。

    白天一直想着,不能惯用户的毛病。

    然后到了晚上,我一想,用户不就是我么,除了我谁还用我写的这个类,就果断用了默认值。

    另外,因为XmlDownloader这个类是不需要实例的,所以:

      1. 把无参构造函数限制成了私有的,这样别人就没法访问构造函数,也就没法实例化它。

      2. 去掉了几乎所有getter方法,同时把所有方法和属性定为私有的,因为不会存在任何XmlDownloader对象,也就没有必要对外开放任何接口。

      2.3.3 求不提反射。

      3. 要记得给Builder类加上static关键字,因为我们需要通过外部类来直接访问它,如果忘了的话,就会出现这样的一个错误:

    No enclosing instance of type XmlDownloader is accessible. Must qualify the allocation with an enclosing instance of type XmlDownloader (e.g. x.new A() where x is an instance of XmlDownloader).

    总的来说还是挺好用的,而且也不难,最关键的是

    优雅!

    用了设计模式之后我整个人都升华了你知道吗

  • 相关阅读:
    python模块—socket
    mac os系统的快捷键
    教你如何将UIImageView视图中的图片变成圆角
    关于ASP.NET MVC
    iOS 日期格式的转换
    将App通过XCode上传到AppStore 出现这个错误“An error occurred uploading to the iTunes Store”的解决方法
    关于MAC OS下面两个软件的功能改进——Dictionary和Fit 输入法
    分享一下上个星期的香港行程
    【博客园IT新闻】博客园IT新闻 iPhone 客户端发布
    解决Entity Framework Code First 的问题——Model compatibility cannot be checked because the database does not contain model metadata
  • 原文地址:https://www.cnblogs.com/chihane/p/3629818.html
Copyright © 2020-2023  润新知