zoukankan      html  css  js  c++  java
  • 重构了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).

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

    优雅!

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

  • 相关阅读:
    Solr服务在Linux上的搭建详细教程
    Linux服务器上安装JDK小白教程
    request和response中文乱码问题后台处理办法
    Redis的五种数据类型及方法
    Java类装载器ClassLoader
    Git快速入门和常用命令
    redis在Linux上的部署和jedis简单使用
    Linux常用基础命令
    JDK1.7中HashMap底层实现原理
    微信电脑版无法显示图片无法下载文件
  • 原文地址:https://www.cnblogs.com/chihane/p/3629818.html
Copyright © 2011-2022 走看看