編寫可讀代碼的藝術之一

《編寫可讀代碼的藝術》,藝術是表達自己內在的慾望
再看看我畢設中的代碼,寫的真是爛啊
可讀代碼的藝術包含:

  • 名副其實的命名
  • 子解釋的註釋
  • 言簡意賅的控制結構

在畢設中遇到的實際問題:

/**
     * 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結束yesnoyesyesnoyesyesno
  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裏面的控制言簡意賅的控制結構的案例

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章