编写可读代码的艺术之一

《编写可读代码的艺术》,艺术是表达自己内在的欲望
再看看我毕设中的代码,写的真是烂啊
可读代码的艺术包含:

  • 名副其实的命名
  • 子解释的注释
  • 言简意赅的控制结构

在毕设中遇到的实际问题:

/**
     * This method evaluates an event against a run, for skip-till-any-match
     * @param e The event which is being evaluated.
     * @param r The run which the event is being evaluated against.
     * @throws CloneNotSupportedException
     */
    public void evaluateEventForSkipTillAny(Event e, Run r) throws CloneNotSupportedException{
        boolean checkResult = true; 
        checkResult = this.checkPredicate(e, r);// check predicate
            if(checkResult){ // the predicate if ok.
                checkResult = this.checkTimeWindow(e, r); // the time window is ok
                if(checkResult){// predicate and time window are ok
                    this.buffer.bufferEvent(e);// add the event to buffer
                    int oldState = 0;
                    int newState = 0;           
                        Run newRun = this.cloneRun(r); // clone this run                
                        oldState = newRun.getCurrentState();
                        newRun.addEvent(e);                 // add the event to this run
                        newState = newRun.getCurrentState();
                        if(oldState != newState){
                            this.activeRuns.add(newRun);
                        }else{//kleene closure
                            if(newRun.isFull){
                                //check match and output match
                                if(newRun.checkMatch()){
                                    this.outputMatch(new Match(newRun, this.nfa, this.buffer));
                                    Profiling.totalRunLifeTime += (System.nanoTime() - r.getLifeTimeBegin());

                                }
                            }else{
                                //check proceed
                                if(this.checkProceed(newRun)){
                                    Run newerRun = this.cloneRun(newRun);
                                    this.activeRuns.add(newRun);
                                    newerRun.proceed();
                                    if(newerRun.isComplete()){
                                        this.outputMatch(new Match(r, this.nfa, this.buffer));
                                        Profiling.totalRunLifeTime += (System.nanoTime() - r.getLifeTimeBegin());

                                    }else {
                                        this.activeRuns.add(newerRun);
                                    }
                                }
                            }
                        }



                    }else{
                        this.toDeleteRuns.add(r);
                    }

                }
    }
  1. 先观察上面的代码,计算代码的复杂度
    Cyclomatic Complexity(CC循环复杂度)=edges-nodes+2
  2. 代码的作用

    Created with Raphaël 2.1.0 开始 检测事件 拷贝run,新run添加事件,得到前后状态 添加事件前后边 检测是否输出 输出这棵run的节点 检测是否前进 检测是否完成 输出这棵run的节点 添加run到活动run表 删掉run 结束 yes no yes yes no yes yes no
  3. 分析上面方法的作用

    • 检查事件满足NFA当前状态的起始边,如果满足再检查当前状态是否为克林闭包状态,再检查是否要前进
  4. 修改为evaluateEventForSkipTillAny(Event e,Run run)的作用是移除/添加/前进对run的三个操作
    checkPredicateOptimized(Event e,Run run)的作用是检查事件对run当前状态的所有谓词的检查

    public void evaluateEventOptimizedForSkipTillAny(Event e, Run r) throws CloneNotSupportedException{
        int checkResult = this.checkPredicateOptimized(e, r);
        switch(checkResult){
            case 1:
                boolean timeWindow = this.checkTimeWindow(e, r);
                if(timeWindow){
                    Run newRun = this.cloneRun(r);
                    this.addRunByPartition(newRun);

                    this.addEventToRun(r, e);
                }else{
                    this.toDeleteRuns.add(r);
                }
                break;
            case 2:
                Run newRun = this.cloneRun(r);
                this.addRunByPartition(newRun);

                r.proceed();
                this.addEventToRun(r, e);
        }
    }
    /**
     * Checks the predicate for e against r
     * 对于run,检测e的谓词,检测结果是0为false,1是take或begin,2是proceed
     * @param e The current event
     * @param r The run against which e is evaluated 
     * @return The check result, 0 for false, 1 for take or begin, 2 for proceed
     */
    public int checkPredicateOptimized(Event e, Run r){//0 for false, 1 for take or begin, 2 for proceed

        int currentState = r.getCurrentState();//当前run的状态

        State s = this.nfa.getStates(currentState);//例子会返回run的克林闭包a状态
        //检测事件类型
        if(!s.getEventType().equalsIgnoreCase(e.getEventType())){// event type check;
            return 0;
        }
        //非克林加检测
        if(!s.isKleeneClosure()){
            Edge beginEdge = s.getEdges(0);
            boolean result;
            //result = firstEdge.evaluatePredicate(e, r, buffer);
            result = beginEdge.evaluatePredicate(e, r, buffer);//
            if(result){
                return 1;
            }
        }else{//克林加情况
            //克林加初始化检测,true
            if(r.isKleeneClosureInitialized()){
                boolean result;

                //当将e加入r当中时,检测run是否需要proceed,他是通过将该事件放入下一个状态中进行计算,
                //得到下一个状态,如果这个事件满足下个状态的所有谓词,状态从克林闭包状态前进
                //例如第一次匹配中,2和3事件到来时返回的false,因为它的volume不满足状态1中的谓词。4事件满足,返回true
                result = this.checkProceedOptimized(e, r);//proceedEdge.evaluatePredicate(e, r, buffer);
                if(result){
                    return 2;//前进
                }else{
                //take边
                Edge takeEdge = s.getEdges(1);
                //计算take边
                result = takeEdge.evaluatePredicate(e, r, buffer);
                if(result){
                    //在第一个匹配中,ID为2和3的事件满足,take边
                    return 1;
                }
                }

            }else{//克林加初始化检测,false
                Edge beginEdge = s.getEdges(0);
                boolean result;

                result = beginEdge.evaluatePredicate(e, r, buffer);//
                if(result){
                    return 1;
                }
            }
        }       
        return 0;           
    }

兵哥PPT上编写可读代码的艺术其中包含->言简意赅的控制结构
1. 打平条件分支:用if-else if -else 代替嵌套if
2. 提前返回
3.使用continue

根据这个理论,checkPredicateOptimized()方法可以改为

else if(r.isKleeneClosureInitialized()){}
else{}

的结构。
只是一个简单的改进,15行的方法还没做好呢

附上PPT里面的控制言简意赅的控制结构的案例

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
内容简介 本书揭示了Java程序员如何创建高质量软件的奥秘。Herbert Schildt 和James Holmes两位编程大师通过将Java应用于某些有趣、实用的计算机问题和编程任务中,全面展示了Java语言的强大功能、敏捷性、多样性和艺术性。本书各章内容分别涉及到Java精髓、递归下降的表达式解析器、用Java实现语言解释器、用Java创建下载管理器、用Java实现E-mail客户端和Internet搜索、用Java修饰HTML、显示统计图表、金融应用中的Applet和Servlet、基于AI的问题求解等,每章给出的示例代码都可以直接运行,无需修改,而且读者可以从www.osborne.com站点上免费下载这些代码。本书是亚马逊网站上的五星级图书,相信读者能够通过研读本书大大提高自己的Java开发能力。本书代码示例易懂有趣,设计思想独特,定会使您受益匪浅! 目录 第1章 Java精髓 1 1.1 简单数据类型和对象:完美的平衡 2 1.2 通过垃圾回收实现内存管理 3 1.3 完美的简单多线程模型 3 1.4 完全集成的异常机制 4 1.5 对多态性支持的改进 5 1.6 通过字节码保证可移植性和安全性 5 1.7 丰富的Java API 6 1.8 Applet 7 1.9 继续变革 7 第2章 递归下降的表达式解析器 9 2.1 表达式 10 2.2 解析表达式 11 2.3 表达式的解析 11 2.4 表达式的分解 13 2.5 一个简单的表达式解析器 16 2.6 向解析器中添加变量 24 2.7 递归下降解析器中的语法检查 34 2.8 计算器Applet 34 2.9 一些尝试 37 第3章 使用Java实现语言解释器 38 3.1 解释何种计算机语言 39 3.2 解释器概述 40 3.3 Small BASIC解释器 41 3.4 Small BASIC表达式解析器 61 3.4.1 Small BASIC的表达式 61 3.4.2 Small BASIC的标识符 62 3.5 解释器 66 3.5.1 InterpreterException类 67 3.5.2 SBasic构造函数 67 3.5.3 关键字 68 3.5.4 run()方法 70 3.5.5 sbInterp()方法 71 3.5.6 赋值 72 3.5.7 PRINT语句 73 3.5.8 INPUT语句 75 3.5.9 GOTO语句 76 3.5.10 IF语句 78 3.5.11 FOR循环 79 3.5.12 GOSUB 82 3.5.13 END语句 83 3.6 Small BASIC的使用 83 3.7 对解释器进行增强和扩展 86 3.8 创建自己的计算机语言 86 第4章 使用Java创建下载管理器 88 4.1 深入理解Internet下载流程 89 4.2 下载管理器概述 89 4.3 Download类 90 4.3.1 Download类的变量 94 4.3.2 Download类的构造函数 94 4.3.3 download()方法 95 4.3.4 run()方法 95 4.3.5 stateChanged()方法 99 4.3.6 Action和Accessor方法 99 4.4 ProgressRenderer类 99 4.5 DownloadsTableModel类 100 4.5.1 addDownload()方法 103 4.5.2 clearDownload()方法 103 4.5.3 getColumnClass()方法 103 4.5.4 getValueAt()方法 104 4.5.5 update()方法 104 4.6 DownloadManager类 105 4.6.1 DownloadManager类的变量 111 4.6.2 DownloadManager类的构造函数 111 4.6.3 verifyUrl()方法 111 4.6.4 tableSelectionChanged()方法 112 4.6.5 updateButtons()方法 113 4.6.6 动作事件的处理 114 4.7 编译并运行下载管理器 114 4.8 改进下载管理器 115 第5章 用Java实现E-mail客户端 116 5.1 E-mail内幕 117 5.1.1 POP3 117 5.1.2 IMAP 117 5.1.3 SMTP 118 5.1.4 发送和接收E-mail的一般过程 118 5.2 JavaMail API 118 5.3 一个简单的E-mail客户端 120 5.3.1 ConnectDialog类 121 5.3.2 DownloadingDialog类 126 5.3.3 MessageDialog类 128 5.3.4 MessagesTableModel类 135 5.3.5 EmailClient类 139 5.4 编译并运行E-mail客户端 156 5.5 对基本E-mail客户端的扩展 157 第6章 使用Java搜索Internet 158 6.1 Web搜索程序基础 159 6.2 遵守Robot协议 160 6.3 Search Crawler概述 161 6.4 SearchCrawler类 162 6.4.1 SearchCrawler类的变量 179 6.4.2 SearchCrawler类的构造函数 179 6.4.3 actionSearch()方法 180 6.4.4 search()方法 182 6.4.5 showError()方法 185 6.4.6 updateStats()方法 185 6.4.7 addMatch()方法 186 6.4.8 verifyUrl()方法 187 6.4.9 isRobotAllowed()方法 188 6.4.10 downloadPage()方法 190 6.4.11 removeWwwFromUrl()方法 191 6.4.12 retrieveLinks()方法 192 6.4.13 searchStringMatches()方法 198 6.4.14 crawl()方法 199 6.5 Web搜索程序的编译与运行 202 6.6 对Web搜索程序的思考 203 第7章 使用Java提交HTML 205 7.1 使用JEditorPane提交HTML 206 7.2 处理超链接事件 206 7.3 编写Mini Web浏览器 207 7.3.1 MiniBrowser类 208 7.3.2 MiniBrowser类的变量 213 7.3.3 MiniBrowser类的构造函数 214 7.3.4 actionBack()方法 214 7.3.5 actionForward()方法 215 7.3.6 actionGo()方法 215 7.3.7 showError()方法 216 7.3.8 verifyUrl()方法 216 7.3.9 showPage()方法 217 7.3.10 updateButtons()方法 218 7.3.11 hyperlinkUpdate()方法 219 7.4 Mini Web浏览器的编译与运行 220 7.5 HTML提交程序的应用前景 221 第8章 统计. 图表与Java 222 8.1 样本. 总体. 分布与变量 223 8.2 基本统计值 223 8.2.1 平均数 224 8.2.2 中位数 224 8.2.3 众数 225 8.3 方差和标准差 227 8.4 回归方程式 228 8.5 Stats类的完整代码 232 8.6 绘图数据 235 8.6.1 数据的缩放 236 8.6.2 Graphs类 236 8.6.3 Graphs类的final变量和实例变量 241 8.6.4 Graphs类的构造函数 242 8.6.5 paint()方法 244 8.6.6 bargraph()方法 247 8.6.7 scatter()方法 247 8.6.8 regplot()方法 248 8.7 一个统计表的应用 248 8.7.1 StatsWin类的构造函数 253 8.7.2 itemStateChanged()事件处理器 254 8.7.3 actionPerformed()方法 255 8.7.4 shutdown()方法 255 8.7.5 createMenu()方法 255 8.7.6 DataWin类 255 8.7.7 联合使用 256 8.8 创建一个简单的统计Applet 258 8.9 一点尝试 260 第9章 金融应用中的Applet和Servlet 261 9.1 计算贷款的定期还款额 262 9.1.1 RegPay的成员 266 9.1.2 init()方法 266 9.1.3 actionPerformed()方法 269 9.1.4 paint()方法 269 9.1.5 compute()方法 270 9.2 计算投资的长期收益 270 9.3 计算达到某项长期收益目标所需的投资本金 274 9.4 计算达到某项期望年金所需的初始投资 278 9.5 根据给定投资计算年金的最大值 282 9.6 计算某项贷款的账户余额 286 9.7 创建用于金融类计算的Servlet 290 9.7.1 使用Tomcat 291 9.7.2 测试Servlet 291 9.7.3 把RegPay转换成Servlet 292 9.7.4 RegPayS程序 292 9.8 一些尝试 296 第10章 基于AI的问题求解 297 10.1 表示法和相关术语 298 10.2 组合爆炸问题 299 10.3 搜索技术 300 10.4 问题的描述 301 10.5 FlightInfo类 303 10.6 深度优先搜索 304 10.7 广度优先搜索 313 10.8 添加启发信息 316 10.8.1 爬山搜索 317 10.8.2 爬山搜索的分析 322 10.8.3 最小代价搜索 323 10.8.4 最小代价搜索的分析 324 10.9 查找多个解 324 10.9.1 路径删除 325 10.9.2 节点删除 326 10.10 查找最优解 331 10.11 回到丢失钥匙的例子 336
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值