カロリーメイトください

Barbaroi Ware(バルバロイ・ウェア)という名前でアプリ開発してます

『リーダブルコード』「12章 コードに思いを込める」他 学習記録

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

序文

リーダブルコード学習9日目。
いつの間にか終盤に突入していた。

GitHub

github.com

進捗

  • 12章 コードに思いを込める
  • 13章 短いコードを書く
    (学習時間:3時間)

コード実装部分(一部)

  • 関数を切り出してロジックを一般化する

CodeExample\12章 コードに思いを込める\12-3 この手法を大きな問題に適用する\print-stock-transactions.js

// 3つのテーブルをそれぞれ古いレコードから順に読み込んで
// 時間が一致するレコードを探し出す関数
// 『一致しない行をスキップする』処理が長い
function printStockTransactions() {
  const stockIter = dbRead("stock");
  const priceIter = dbRead("price");
  const numSharesIter = dbRead("num-shares");

  // 3つのテーブルの行を一度にイテレートする
  while (stockIter++ && priceIter++ && numSharesIter++) {
    const stockTime = stockIter.time;
    const priceTime = priceIter.time;
    const numSharesTime = numSharesIter.time;

    if (stockTime !== priceTime || stockTime !== numSharesTime) {
      if (stockTime <= priceTime && stockTime <= numSharesTime) {
        stockIter.nextRow();
      } else if (priceTime <= stockTime && priceTime <= numSharesTime) {
        priceIter.nextRow();
      } else if (numSharesTime <= stockTime && numSharesTime <= priceTime) {
        numSharesIter.nextRow();
      } else {
        throw new error();
      }
      continue;
    }

    // 一致した行を印字する
    print(stockTime);
    print(stockIter.tickerSymbol);
    print(priceIter.price);
    print(numSharesIter.numberOfShares);

    stockIter.nextRow();
    priceIter.nextRow();
    numSharesIter.nextRow();
  }
}

/*******************
 改善例
********************/
// 『一致しない行をスキップする』処理を関数に切り出し、
// ロジックを一般化する
function printStockTransactions() {
  const stockIter = dbRead("stock");
  const priceIter = dbRead("price");
  const numSharesIter = dbRead("num-shares");

  while (true) {
    const time = advanceToMatchingTime(stockIter, priceIter, numSharesIter);
    if (time === null) {
      return;
    }

    // 一致した行を印字する
    print(time);
    print(stockIter.tickerSymbol);
    print(priceIter.price);
    print(numSharesIter.numberOfShares);

    stockIter.nextRow();
    priceIter.nextRow();
    numSharesIter.nextRow();
  }
}

function advanceToMatchingTime(rowIter1, rowIter2, rowIter3) {
  // 3つのテーブルの行を一度にイテレートする
  while (rowIter1 && rowIter2 && rowIter3) {
    const t1 = rowIter1.time;
    const t2 = rowIter2.time;
    const t3 = rowIter3.time;

    if (t1 == t2 && t1 == t3) {
      return t1;
    }

    tmax = max(t1, t2, t3);

    // いずれかの行が遅れているのであれば、その行を進める。
    // 最終的にすべての行が一致するまでwhileループを繰り返す
    if (t1 < tmax) {
      rowIter1.nextRow();
    }
    if (t2 < tmax) {
      rowIter2.nextRow();
    }
    if (t3 < tmax) {
      rowIter3.nextRow();
    }

    return null;
  }
}
  • その他実装部分

github.com

実行結果

ねえよ

感想

「12章 コードに思いを込める」
・・・
ロマンチックですね。

ソースコードは「ロジックを言葉で説明して、ソースコードに落とし込む」の例。

言わんとしていることはわかるんだけど、実際の作業の流れとしては
「汚いコードを書く」→ 「コードが汚いことに気づく」→「ロジックを言葉で説明する」→「そのロジックをコードに落とし込む」ってことでしょう?
「ロジックを言葉で説明する」の段階で最初に書いた汚いコードの影響を思いっきり受けて、こんなきれいなコード書けない気がするなぁ…。
こういう思考に至る過程をもうちょっと説明してほしい気がする。

割とさらっと流してるけど、この章の内容だけで本1冊書けちゃうぐらいのものだと思うので、もうちょっと例が見たかったかな?
いや、それはそれで頭フル回転になるからしんどいかな…。

カロリーメイトください。

BGM

だいたいかんちがい / リアル3区

www.youtube.com