现在的位置: 首页 > 综合 > 正文

“代码三要素”是一个大课题,牵涉的不仅仅是代码质量问题

2013年10月07日 ⁄ 综合 ⁄ 共 2406字 ⁄ 字号 评论关闭

        在一定前提下,代码要以容易理解的方式实现。这个课题包括的内容太广,此文仅就近段时间读的一段简单程序为例说明一下似乎与“单入口单出口”原则相关的内容。而谈及这个原则,也可以从不同角度和不同代码形式来谈,此文仅就下面代码模型中的形式而谈。下面代码的背景是有三种unit,每种unit有相同种类的多个documentType;代码实现的是获取每种unit下每种documentType数量。代码如下所示:

       

 

import java.util.ArrayList;

import java.util.HashMap;

import java.util.Iterator;

import java.util.List;

import java.util.Map;

 

public class DocsGroup{

 

    List<HashMap>docList = new ArrayList<HashMap>();

    HashMap<String, Object>map = null;

 

    public Map<String,List> find(List<String> DocTyps) throws Exception {

        

        //遍历所有文档,获取相关信息

        for ( String fileType :DocTyps){

            searchAndMapData(fileType);

        }

        //设置返回值

        Map<String,List> res = new HashMap<String, List>();

        res.put("docList", docList);

        return res;

    }

 

    /**

     * 获取指定文档相关信息

     */

    private void searchAndMapData(String documentType){

        

        //获取1单元信息

        this.searchAndMapDataSupport( documentType, "1");

        //获取3单元信息

        this.searchAndMapDataSupport( documentType, "3");

        //获取5单元信息

        this.searchAndMapDataSupport( documentType, "5");

    }

    private void searchAndMapDataSupport(String documentType,String unit){

        

        int count = this.fetchCount(documentType, unitValue);

        if(count>0){

            map = new HashMap<String, Object>();

            map.put("documentType", documentType);

            map.put("unit", unit);

            map.put("Count", count);

            docList.add(map);

        }

    }

}

 

        上面的程序有很多值得肯定的地方,如它的模块化程度已经很高,后面两个私有方法为前面的find方法做服务,如果将后两个方法内容去不合并到find方法中,那find的复杂程度将大大提高,而维护难度也加大很多(要清楚,这个代码模型中的每个方法中实际上会包含很多逻辑关系的)。如果可以把GOF设计模式,那find和searchAndMapData就相当于是一种外观模式——一种特殊的外观模式——其特殊不仅是体现在方法上提设计模式,也体现在searchAndMapData方法中的隐含性,例如所调用的方法是相同而简单,实际上可能是不同而复杂的。

        在编码开始之前一定要好好分析要出来的业务,对业务进行建模分析,认真考虑数据结构。编写程序指做三件事情——输入、处理和输出——而这些无不与数据结构有关,此外对业务的分析最终在代码上体现的也是一个用户输入和展示信息。

        按照上面的说法,分析上述代码返回结果的数据结构,是map里有一个list,将每种documentType作为一个map存放到此List中,在结合上述业务场景,则会发现业务上有多少种documentType,List中就会有三倍于这个数字的map。如果我们换个角度想一下,将每种Unit做为一个map,在要返回的信息可以作为DTO放到map中进行返回。当然,我们还可探究此处的数据结构有没有必要这么复杂,但此文不讨论哪种数据结构更好,只是阐述一下在coding前要对业务分析,对数据结构进行设计。

        深入到代码细节我们会发现,在类内定义了两个公共变量,主要用于接收要返回的信息。正是这种定义方式加上一种非常规的输入输出的操作导致读这段很简短的代码有些吃力。首先在在find方法中不能很明确的告诉我们返回值从何处获取的。原因是,虽然我们调用了一个获取返回值得处理过程searchAndMapData,但它的职责却绝非是一般意义上的过程,对比函数我们会清楚这个过程其实担当着函数的角色却披着件过程的皮(当然过程在多返回值的处理中等是可以发挥相当作用的,但应该考虑更容易让人理解的方式,此话题是另一个维度的问题,在此不做延展)。另外,还要注意到这两个变量是根本没必要作为公共变量的。姑且将这类问题广义的归结到“单入口,单出口”原则上,不能说这种原则完全正确或有必要,但它也确实为代码的清晰和质量做着贡献。正如百科所言,它是为了保证开发程序的质量,要求过程中的数据流控制是必须在固定的程序段入口进入,固定的出口返回,不允许在编程中随意使用数据。产生这类问题很多原因在于没有对内部逻辑进行真正的规划设计,仅仅是在coding……

        上述代码虽看似像是单入口单出口不明确引起的代码不清晰,但其实质及其可挖掘的地方却远不止于此。说复杂了这涉及的是业务分析,设计分析和数据模型分析,说简单了其实就是要认真对待“输入、处理、输出”三要素,而这三要素所涉及的不仅仅是代码的清晰与否问题,更关系到其质量,关系到其韧性,乃至整个业务的完整性!

抱歉!评论已关闭.