抽出関数Extract Function

15736 ワード


背景


コード・セグメントを見つけて、何をしているのかを理解し、独立した関数として抽出し、名前を付けます.
コードを独立した関数にバンドルするタイミングについては数え切れないほどの意見がある.まず、長さを基準にすることができます.関数が画面を超えてはいけないルールを考えることができるとします.再使用性を基準にすることもできます.2回以上使用したコードを関数とし,1回のみ使用したコードをインライン状態とする.しかし、私から見れば、「目的と分離」の実現方法が最も合理的な基準だ.コードを見極め、何をしているのかを把握するのに時間がかかる場合は、関数として抽出し、「何が起こっているのか」に合った名前を付けます.これにより,後でコードを読み直す際に関数の目的が明らかになるが,本稿のコード(その関数が目的を達成するために具体的に実行される操作)については,ほとんど心配することはない.

プログラム

  • 関数を再作成し、目的の名前をよく表示します.△「どうするか」ではなく、「何をするか」です.
  • ターゲットコードが1つの関数呼び出し文のように非常に簡単であっても、それを関数として抽出することができ、ターゲットにより良い名前を付けることができれば.このような名前が思い出せないと、関数で抽出できない信号です.しかし抽出の過程で良い名前が出てくるので、最初から一番いい名前を取る必要はありません.いったん抽出して関数として使用すると,効果が大きくなければ,元の状態に再結合できる.この過程で悟れば、時間を無駄にしない.オーバーラップ関数をサポートする言語を使用すると、抽出した関数が元の関数にオーバーラップします.これにより、次のステップで実行する有効範囲を超えた変数を処理する操作を低減することができる.関数を元の関数から削除する必要がある場合は、関数の削除をいつでも適用できます.
  • ソース関数から抽出するコードを
  • コピーし、新しい関数に貼り付けます.
  • で抽出されたコードでは、元の関数の領域変数を参照して、私が抽出した関数の有効範囲を超えた変数があるかどうかを確認します.ある場合はパラメータとして渡されます.
  • この問題は、
  • ソース関数の重畳関数として抽出される場合には発生しません.
  • の一般的な関数には、領域変数とパラメータがあります.最も一般的な処理方法は、これらの変数を係数に渡すことです.使用できますが、値が変わらない変数は通常、このように簡単に処理できます.
  • で抽出されたコードでのみ使用される変数宣言が抽出された関数の外にある場合は、抽出された関数で宣言するように変更されます.
  • で抽出されたコードでは、変換値の変数で値に渡されるものを処理することに注意する.変数が1つしかない場合は、抽出されたコードをクエリー関数として使用し、その変数に結果(戻り値)を代入します.
  • では、抽出されたコードで値を変更する領域変数が多すぎる場合があります.この場合、関数の抽出を停止し、変数の分割や一時変数をクエリー関数に変換するなどの他の機能を適用して、変数を使用するコードを簡略化します.次に、関数抽出を再試行します.
  • 変数の処理が完了すると、コンパイルされます.
  • のコンパイル言語を開発している場合は、すべての変数を処理してからコンパイルします.処理されていない変数を探すのに役立つことが多い.
  • ソース関数から抽出するコード部分を、新しく作成した関数を呼び出す文(すなわち、抽出した関数に作業を委任する)
  • に変換する.
    テスト
  • .
  • 他のコードに、先ほど抽出したコードと同じまたは類似のコードがあるかどうかを確認します.ある場合は、さっき抽出した新しい関数を呼び出すように変更したかどうかを確認します.(インラインコードを関数呼び出しに変換)

  • before

    function printOwing(invoice){
      let outstanding = 0;
      
      console.log("**************");
      console.log("****고객채무****");
      console.log("**************");
      
      //미해결채무(outstanding) 계산
      for(const o of invoice.orders) {
        outstanding += o.mount;
      }
      
      //마감일(dueDate)기록
      const today = Clock.today;
      invoice.dueDate = new Date(today.getFullYear(), today.getMonth()),
        today.getDate() + 30);
      
      // 세부사항 출력
      console.log(`고객명: ${invoice.customer}`);
      console.log(`채무액: ${outstanding}`);
      console.log(`마감일: ${invoice.dueDate.toLocalDateString()}`);
    
    }

    after

    function printOwing(invoice){
      
      printBanner();
      
      const outstanding = calculateOutstanding();
      recordDueDate(invoice);
      printDetails(outstanding);
      
      
      function printBanner() {
        console.log("**************");
     	console.log("****고객채무****");
      	console.log("**************");
      }
      
      function calculateOutstanding(invoice) {
         let result = 0;
      	 for(const o of invoice.orders) {
            result += o.mount;
         }
         return result;
      }
      
      function recordDueDate(invoice) {
        const today = Clock.today;
        invoice.dueDate = new Date(today.getFullYear(), today.getMonth()),
        today.getDate() + 30);
      }
      
      function printDetails(nvoice,outstanding) {
        console.log(`고객명: ${invoice.customer}`);
        console.log(`채무액: ${outstanding}`);
        console.log(`마감일: ${invoice.dueDate.toLocalDateString()}`);
      }
     
      function printDetails(i) {
        console.log(`고객명: ${invoice.customer}`);
        console.log(`채무액: ${outstanding}`);
      }
        
    }

    リファレンス


    マーティン・パラーゼ2版再構築