文档章节

生拉硬套设计模式(一),关于装饰者模式在Android项目中的运用。

bAnxIan_coder
 bAnxIan_coder
发布于 2015/04/30 10:53
字数 1704
阅读 42
收藏 2

                                                   转载请注明出处,尊重作者劳动成果,谢谢!

    个人觉得设计模式其实有以下两点好处,

    1.可以在大型项目中增加可扩展性可维护性。

    2.可以让你的编程更加美观和具有艺术性。

    以上两点我一直觉得是作为一个标准程序员理应追求的境界,而不是光为了实现业务功能完成任务而写代码。


    进入正题,以前编程的时候碰到一个问题,有一个水果类,有的页面是水果列表,服务端传回的数据是当前列表页(listview)需要用到的属性,有的是水果详情页(一堆layout),需要用到的又是水果其他不同的属性,有的是购物车里面的水果列表。这些数据都是从服务端返回的,我们肯定是需要解析的,而且一般我们Android的数据交互大多数都是用json作为和服务端的数据解析。


    水果列表用到了,id,img,name,maketPrice(这个属性好扯淡)等属性,

    水果详情页又用到了,id,name,img,productPlace(产地)等属性,

    购物车列表页用到了,id,name,img,countNum(购买数量)等属性,


    这个时候我们出于整体代码的维护性和扩展性尤其是为了单个类的可阅读性等考虑,很明显针对每一个不同的Json数据分别写一个解析类是很傻比的事情,思考之后就可以看得出来这些解析分别都有重复的解析字段,于是我就使用一个基类来保存id,name,img,三个属性,然后再分别新建不同的子类继承之,在子类里面再多出其他的解析代码来解析多余的属性。这样想想看应该是非常完善的。

    但是这里有一个问题:    如果又多了一个页面,既需要用到maketPrice这个属性也需要用到productPlace属性,那是应该重新写一个子类继承父类然后再新增maketPrice和productPlace呢还是用其他的方法,或者大家再思考远一点,接下来的新业务还会有更多的扩展类需求,那都是不断的重写父类的解析法方法吗。这个方法显然不够具有艺术性以及导致大量代码的重复性。(用我们老大的话来说就是一点都不够专业)


   最近在看老罗的源代码情景分析才了解到Android的UI层用了大量的装饰者模式(关于装饰者模式的具体概述,大家可以移步这个博客 http://blog.csdn.net/lenotang/article/details/2587265于是恍然大悟原来我碰到的问题可以用这个模式解决,于是生拉硬套了一番。代码如下:


    首先是水果实体类 FruitItemBean:

public class FruitItemBean implements Parcelable{
    
    private int productId;// 产品Id
    private String name;// 标题
    private String imgs;// 图片地址
    
    private double marketPrice;// 市场价
    private String productPlace;//产地
    private int countNum;//购买数量
}

    

    然后是所有json解析类的解析接口

/**
 * 标题:FruitItem数据解析接口
 * 作者: wxc
 * 时间: 2015/4/29
 */
public interface Helper {

    public FruitItemBean getJsonData(JSONObject obj);

}

     

    装饰者类

/**
 * 标题:装饰者类
 * 作者: wxc
 * 时间: 2015/4/29
 */
public class DecorHelper implements Helper {

    private Helper mHelper;

    public DecorHelper(Helper helper) {
        mHelper = helper;
    }

    @Override
    public FruitItemBean getJsonData(JSONObject obj) {

        if (mHelper != null) {
            return mHelper.getJsonData(obj);
        }
        return mHelper.getJsonData(obj);
    }
}

    

    基础解析类

/**
 * 标题:基础解析类
 * 作者: wxc
 * 时间: 2015/4/29
 */
public class FruitBaseHelper implements Helper{

    @Override
    public FruitItemBean getJsonData(JSONObject obj) {
        FruitItemBean item = new FruitItemBean();
        
        //json解析建议大家自己手写一个工具类或者git上下载
        item.setProductId(JsonUtil.getInt(obj, "id", 0));
        item.setName(JsonUtil.getString(obj, "name", ""));
        item.setImgs(JsonUtil.getString(obj, "imgs", ""));

        return item;
    }  
}

     

    水果列表页解析类

/**
 * 标题:水果列表所有数据
 * 版权: 维度
 * 创建时间: 2015-3-18 
 * 作者:wxc
 */
public class FruitItemHelper extends DecorHelper {

    public FruitItemHelper(Helper helper) {
        super(helper);
    }

    public FruitItemBean getJsonData(JSONObject obj) {
        FruitItemBean item = super.getJsonData(obj);

        item.setMarketPrice(JsonUtil.getDouble(obj, "marketPrice", 0));
        return item;
    }
    
     //这个是解析列表的方法
    public  List<FruitItemBean> getFruitItemList(JSONObject obj) {
    List<FruitItemBean> list = CollectionUtil.newArrayList();

    JSONObject data = JsonUtil.getJSONObject(obj, "data");
    JSONArray array = JsonUtil.getJsonArray(data, "itemList");
    if (array != null && array.length() > 0) {
        int length = array.length();
        for (int i = 0; i < length; i++) {
            try {
                list.add(getJsonData(array.getJSONObject(i)));
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }
    return list;
  }   
}

   

    水果详情页解析类

/**
 * 标题:水果详情页解析
 * 作者: wxc
 * 时间: 2015/4/29
 */
public class FruitInfoHelper extends DecorHelper {

    public FruitInfoHelper(Helper helper) {
        super(helper);
    }

    public FruitItemBean getJsonData(JSONObject obj) {
        FruitItemBean item  = super.getJsonData(obj);

        item.setProductPlace(JsonUtil.getString(obj, "productPlace", ""));        
        return  item;
    }

}

    

    水果购物车页解析数据类

/**
 * 标题:水果购物车页解析
 * 作者: wxc
 * 时间: 2015/4/29
 */
public class FruitShopCartHelper extends DecorHelper {

    public FruitShopCartHelper(Helper helper) {
        super(helper);
    }

    public FruitItemBean getJsonData(JSONObject obj) {
        FruitItemBean item  = super.getJsonData(obj);

        item.setCountNum(JsonUtil.getString(obj, "countNum", ""));        
        return  item;
    }

}

    

    接下来是具体调用

//调用列表解析
List<FruitItemBean> list =new FruitItemHelper(new FruitBaseHelper()).getFruitItemList(json);
//调用详情解析
FruitItemBean item = new FruitInfoHelper(new FruitBaseHelper()).getJsonData(json);
//调用购物车解析
List<FruitItemBean> shoppingList = new FruitShopCartHelper(new FruitBaseHelper())
                                                                   .getFruitItemList(json);

    从这里可以看到,我刚才提出来的问题,如果有一个页面需要同时用到marketPrice和productPlace的时候只需要调用

FruitItemBean item = new FruitInfoHelper(new FruitItemHelper(new FruitBaseHelper()))
                                                                    .getJsonData(json);

    有没有觉得很熟悉!!!!是不是曾经看到过这种调用!!!对!!!没有错!!!!除了androidUI组件,Java的IO流也大量用到了装饰者模式!比如 BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("..")));这样。是不是感觉!!!卧槽!!!!原来装饰者模式咱们都用过!!!好啦。。用过不代表会写。领悟才是王道。

     到了这里已经把我自己的所有代码都重构完了,此文只给出了一种具体思路,由于本人一直都在创业团队做主程,没在大公司混过(真特么相进阿里啊!),对这种架构只能自己YY了,大家看看就好,我是属于无脑的生拉硬套。有更好的解决办法欢迎交流。



© 著作权归作者所有

bAnxIan_coder
粉丝 6
博文 14
码字总数 13487
作品 0
杭州
程序员
私信 提问
Java 设计模式(14) —— 复合模式

一、复合模式 模式常一起使用,组合在一个设计解决方案中 复合模式在一个解决方案中结合两个或多个模式,能解决一般性或一系列的问题 二、示例 本次设计模式讲解中无代码示例,由于复合模式是...

磊_lei
2018/05/26
0
0
Android 设计模式-装饰模式(Decorator Pattern)

定义 饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。 UML结构图 Component:组件对象接口 Concre...

Code猎人
2018/05/10
0
0
Android 装饰者模式初探

前提 最近刚换了一份工作,这段时间一直在熟悉公司的代码逻辑,从中受益颇多。里面的设计模式也挺多的,运用的那个潇洒飘逸,让我好生羡慕。自己对设计模式这块理解的不是特别的深入,能拿出...

Silence潇湘夜雨
2018/07/03
0
0
《JavaScript设计模式与开发实践》模式篇(12)—— 装饰者模式

在传统的面向对象语言中,给对象添加功能常常使用继承的方式,但是继承的方式并不灵活, 还会带来许多问题:一方面会导致超类和子类之间存在强耦合性,当超类改变时,子类也会随之 改变;另一方...

嗨呀豆豆呢
2018/12/25
0
0
JavaScript常用设计模式

设计模式 设计模式是一种在长时间的经验与错误中总结出来可服用的解决方案。 设计模式主要分为3类: 创建型设计模式:专注于处理对象的创建 Constructor构造器模式,Factory工厂模式,Singl...

a独家记忆
2018/07/13
0
0

没有更多内容

加载失败,请刷新页面

加载更多

gradle grovvy中的闭包

1. 无参数的闭包 //这b1就是一个闭包def b1={ println "hello b1"}//定义方法,包含闭包类型的参数def method1(Closure closure){closure()}//执行method1method1(b1) 执行结果 ...

edison_kwok
29分钟前
3
0
基于Spring Boot + Dubbo的全链路日志追踪(一)

一、 概要 当前公司后端整体架构为:Spring Boot + Dubbo。由于早期项目进度等原因,对日志这块没有统一的规范,基本上是每个项目自己管自己的日志。这也对后面的问题排查带来了很大的困难,...

明天以后
今天
7
0
安装fastdfs文件服务器步骤

1、安装libfastcommon wget https://github.com/happyfish100/libfastcommon/archive/master.zip 解压后安装 cd fastcommon-master ./make.sh ./make.sh install 2、安装 FastDFS,从sourcef......

lsjlgo
今天
3
0
MySQL 5.7 免安装版配置

下载地址:https://dev.mysql.com/downloads/mysql/ 安装步骤 1.下载zip解压到目录下 2.配置环境变量 新建系统变量:MYSQL_HOME,值:D:\DevelopmentTool\Mysql-5.7.26-winx64 修改path变量:...

华山猛男
今天
7
0
java map的遍历

//从大的角度可以分为两类Set<String> set=map.keySet();这里面还可以分为3类, 从set的角度来分 //Set<Map.Entry<String, String>> entery=map.entrySet(); public class Test { public sta......

南桥北木
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部