コード匂い21 -匿名の機能乱用者


機能、ランムラ、閉鎖.とても高い、非宣言的で、熱い.

TL;DR: Don't abuse closures and functions. Encapsulate them into objects.


問題


  • 保守性
  • テスト可能性
  • コード再利用
  • を隠す
  • 実装
  • のデバッグ

    解決策

  • ラップ機能/閉鎖
  • メソッドオブジェクト/戦略
  • のアルゴリズムを修正します

    サンプルコード


    間違い


    sortFunction = function(arr, fn) {
      var len = arr.length;
    
      for (var i = 0; i < len ; i++) {
        for(var j = 0 ; j < len - i - 1; j++){  
          if (fn(arr[j], arr[ j+ 1])) {
            var temp = arr[j];
            arr[j] = arr[j+1];
            arr[j + 1] = temp;
          }
        }
      }
      return arr;
    }
    
    scores = [9, 5, 2, 7, 23, 1, 3];  
    sorted = sortFunction(scores, (a,b) => {return a > b});
    


    class ElementComparator{
      greatherThan(firstElement, secondElement){
        return firstElement > secondElement;
        //This is just an example. With more complex objects this comparison might not be trivial
      }
    }
    
    class BubbleSortingStrategy {
      //We have a strategy, we cant unit test it, change for a polymorphic,
      //Swap and benchmark algorithms etc.
      constructor(collection, comparer){
        this._elements = collection;
        this._comparer = comparer;
      }
      sorted(){ 
        for (var outerIterator = 0; outerIterator < this.size() ; outerIterator++) {
          for(var innerIterator = 0 ; innerIterator < this.size() - outerIterator - 1; innerIterator++){  
            if (this._comparer.greatherThan(this._elements[innerIterator], this._elements[ innerIterator + 1])) {
              this.swap(innerIterator);  
            }
          } 
        } 
        return this._elements; 
      }
      size() {
        return this._elements.length;
      }
    
      swap(position){    
        var temporarySwap = this._elements[position];
        this._elements[position] = this._elements[position + 1];
        this._elements[position + 1] = temporarySwap;
      }
    } 
    
    scores = [9, 5, 2, 7, 23, 1, 3]; 
    sorted = new BubbleSortingStrategy(scores,new ElementComparator()).sorted();
    

    検出

  • クロージャと匿名の関数は、コードブロックをモデル化するために非常に有用です.
  • タグ

  • のプリミティブ
  • の乱用者
  • 結論


    人間はコードを読む.ソフトウェアは匿名関数でOKですが、複数のクロージャが起動されると保守性が損なわれます.

    関係




    クレジット


    Roman MagerUnsplashによる写真

    Object-oriented programming increases the value of these metrics by managing this complexity. The most effective tool available for dealing with complexity is abstraction. Many types of abstraction can be used, but encapsulation is the main form of abstraction by which complexity is managed in object-oriented programming.


    レベッカWirfsブロック


    この記事はCodesmellシリーズの一部です.


    最終更新日: 2021/07/03