書籍「リーダブルコード」 4章 まとめ

美しいコードは読みやすい

鍵となる考え方:一貫性は「正しい」より大切

一貫性のある簡潔な改行位置

単位を補足するようなコメントは、一箇所にまとめた方が簡潔で分かりやすくなる。

これよりも

public statc Car car1 = 
    new Car(
        180,    /*km/h*/
        200     /*ps*/
        1200    /*cc*/
    );

public statc Car car2 = 
    new Car(
        120,    /*km/h*/
        250     /*ps*/
        660     /*cc*/
    );

こちらの方が読みやすい。

//Car(maxSpeed, maxPower, engineDisplacement)
//    [km/h]    [ps]     [cc]

public static Car car1 = new Car(180, 200, 1200);
public static Car car2 = new Car(120, 250, 660);
メソッドを使った整列

何度も同じ処理を行なってるようだったらメソッド化する。

※悪い例

string error = "";
assert(ExpandFullName(database_connection,  "Kato", &error)
    = "Mr. Kato");
assert(error = "");
assert(ExpandFullName(database_connection,  "Ato", &error) = "");
assert(error = "no match found");

※いい例

void CheckFullName(string partial_name,
                   string expected_full_name, 
                   string expected_error){
    string error;
    string full_name = ExpandFullName(database_connection,  partial_name, &error);
    assert(error == expected_error);
    assert(full_name == expected_full_name);
}

checkFullName("Kato","Mr.kato","")
checkFullName("Ato","Mr.Ato","no match found")

下のコードは以下のようなメリットがある。

  • テストコードとケースの可読性の向上
  • メソッド化したことで、テストの追加が容易になった

コードの見た目を良くすることは、表面だけでなく構造も改善にも繋がる。

縦の線をまっすぐにする

コードの要素を縦に整列させることで見やすくなり、僅かな差異によるミスも減らせる。

checkFullName("Ryo Kato","Mr.kato","")
checkFullName("Ato"     ,"Mr.Ato" ,"no match found")
checkFullName("none"    ,""       ,"no match found")

但し、コードを整列する手間や、一部を変更した際に全体も変更しなければならないため、最低限以下のことを意識する。

似ているコードは、なるべく似ている見せ方をする

一貫性と意味のある並び

複数のコードの要素を並べる際は、以下のことを意識しながら、意味のある並べ方をした方がいい。

  • 対応するHTMLのフォームの並びを踏襲
  • 重要度順に並べる
  • アルファベット順

また、途中で並べ方を変えると混乱するので、全体で統一すべきである。

宣言をブロックにまとめ、手順を明確にする
  • 手順ごとにコードを単位化する
  • 単位ごとに段落分けする

書籍「リーダブルコード」 3章 まとめ

3章

誤解されない名前

名前が「他の意味と間違われることはないだろうか?」と何度も自問自答する

積極的に「誤解」されそうな部分を探していく。

filter
results = DB.all_objects_filter("a")

このようにメソッド名がfillterだけでは、取り出せる値に「aである」「aでない」の2つの意味で解釈される可能性がある。

aを「選択」するのであればselect()。「除外」するのであればexclude()の方が適切。

限界値は「min」「max」

カートに入る限界値を示す「CART_TOO_BIG_LIMIT」は、限界値(limit)が「未満」と「以下」のどちらか分からない。

限界値「以下」としたいのであれば、「MAX_ITEMS_IN_CART」とした方がより明確である。

ブール値の名称

命名時に意識すること

  1. 名称から二つの意味を捉えられないようにする
  2. 「is」「has」「can」「should」などを活用する
  3. 肯定形にする(否定形は避ける)
ユーザーの期待に合わせる

ユーザーの持つ先入観から、誤解されないような命名を行なう。

例えば、一般的に「get」や「size」はメンバ値を返すだけの軽量な処理が期待されるため、それを裏切らない処理を記述する。

「自分さえ分かればいい」「ドキュメントにそう書いたから文句を言うな」ではなく、なるべく誤解を招かないような名前を採用することで、事故の発生は抑制できる。

複数の名前を検討する

誤解されるあらゆる可能性を考えて、何パターンも名前を検討して意図をより明確にしていく。

書籍「リーダブルコード」 2章 まとめ

2章

名前に情報を詰め込む

プログラミングにおける命名(変数や関数など)は、なるべく多くの情報を詰め込むようにする。

「名前は短いコメント」

具体的には、以下のようなことを意識して命名を行なう。

明確な単語を選ぶ

例えば「getPage」という関数名からは、どこからページを取得するのか分からない。仮にネット上から取得するのであれば、「downloadPage」の方がより明確。

汎用的な名前を避ける

例えば「tmp」「retval」「foo」などの、どこにでもあり、意図が明確に伝わらないような名前。

tmp

一時的に値を保持するという意味合いで使われることが多く、適切に扱われている場面もある。

例 (左 > 右のとき、値を入れ替える)

if left > right:
    tmp = right
    right = left
    left = tmp

この場合は、以下のような理由から問題が無いと言える。

  • tmpの生存期間がたったの3行
  • 値の一時保持以外の役割がない

但し、関数の引数や、長期に渡る値の保持に用いるのは不適切である。

retval

retvalは関数の返り値を表す変数名として使われがち。

例 (配列の2乗の合計を返す関数)

def euclidean_norm(nums):
    retval = 0.0
    for value in nums:
        retval += value * value
    return retval

この場合、「retval」だけでは情報が不足しているため、「sum_squares」という変数名の方がより明確である。

ループイテレータ

「i」「j」「k」などは、ループイテレータとして使う分には問題ない。但し、複数のイテレータが存在する場合、以下のようにすることで情報がより明確になる。

clubs[ci].members[mi] == users[ui]
#各要素の頭文字と組み合わせている

抽象的な名前より具体的な名前

変数や関数などの構成要素の名前は、抽象的なものではなく具体的なものにする。

例えば「--run_localy」というコマンドオプションが存在したとする。

  • デバッグ情報を印字する機能を持つが、その分遅くなる
  • ローカル環境のみで使用、リモートではパフォーマンスを阻害するため未使用

しかしこの場合は、「--extra_logging」(ログの追加)という名前の方が明確である。なぜなら以下のような問題があるから。

  • ローカルで動かす時に使用されるのは分かるが、どんな機能を持っているか分からない
  • リモートでデバッグ情報を表示したい時、リモートなのに「localy」という矛盾が発生する
  • ローカルでパフォーマンステストしたいときは利用されない
名前に情報を追加
単位

値などを保持する場合、単位情報を追加する。

元の引数 単位を追加
delay delay_secs
size size_mb
limit max_speed
angle degrees_cw
重要な情報

セキュリティの問題や、データの形式などの情報も追加した方がいい。

状況 変数名 状況を追加した変数名
プレインテキストのパスワード(暗号化が必要) password plaintext_password
エスケープ未処理のコメント comment unescaped_comment
utf8に変換されたhtml html html_utf8
URLエンコードされたデータ data data_urlenc

ただし、全ての変数に適用するのではなく、間違えたらバグになりそうな部分にのみ使うべきである。

変数の長さの決め方

命名時は「長い名前を避ける」という暗黙的な制約がある。

スコープが小さければ短くてもいい

スコープ(名前が見えるコードの行数)が小さければ、わざわざ多くの情報を詰め込む必要はない。

def debug():
    m = userMail()
    print m

要するに、全体でコードを理解するために十分な要素があればいい

但し、クラスのメンバや引数などのスコープの広い変数には、相応に情報を含まなければならない。

def debug(m):
    print m

これだとmの意味が分からない。 あくまで「必要な情報を含んだ上」で、名前が長くなるのは問題無い。

頭文字と省略形

名前を省略する場合は、プロジェクト固有の省略形は避け、新しくプロジェクトに参加したメンバーでも理解できるような命名を行なう。

例えば、クラス名「BackEndManager」を「BEManager」と表記しても、新しいメンバーは理解できないだろう。

(誰もが知っているような「String」を「str」、「document」を「doc」などは問題ないと言える)

不要な単語は削る

特定の単語を削除しても、情報が損なわれない場合は削除すべき。

変換元 変換後
convertToString toString
doServelLoop servalLoop

名前のフォーマットで情報を伝える

エンティティごとに命名法則を変えることで、区別がしやすくなる。

class LogReader{
    public:
        void OpenFile(string local_file);

    private:
        int offset_;
        DISALLOW_COPY_AND_ASSIGN(LogReader);
}

書籍「リーダブルコード」 1章 まとめ

1章

理解しやすいコード

コードは読みやすく書かなければならない

このコードは、

b = 1 if a == 2 else 2 if a ==2 else 0

以下のコードよりも優れていると思いがち。

if a = 1:
   b = 1
elif a = 2:
   b = 2
else:
   b = 0

前者の方が簡潔ではあるが、後者の方が理解はしやすい。

読みやすさの基準は、他の人が最短で理解できるように書くこと

これは、自分だけが利用するコードでも言える。

小さいことは絶対にいいことか

コードは短くした方がいいが、「理解するまでにかかる時間」を短くする方が大事。

他の目標との競合

理解しやすくコードを書くことは、コードの効率化や設計のしやすさを阻害することはない。(むしろ良い影響を与える)

少し冗長なところを見かけても、すぐにリファクタリングはせず、まず「このコードは理解しやすいのだろうか?」と考えることが大切。

書籍 プリンシプルオブプログラミング 第7章 まとめ

7章

法則 〜プログラミングのアンチパターン

7.1 ブルックスの法則

要員追加は火に油

スケジュールより遅れている案件に対し、単純に人を追加すると「依存関係によるオーバーヘッド」「教育に時間が取られる」といった要因から、さらなるスケジュールの遅延を招いてしまう。

プログラマは等価交換できない

一人のプログラマを別のプログラマに交換したところで、質や経験の差から必ず同じ生産能力になるとは限らない。 同様に急に人数を追加しても、それに比例してチームの生産能力が上がるわけではない。

リスケジュールをする

無条件に人員を投入するのではなく、リスケジュールが最も効果的である。その際は、クライアントと相談しながら各機能に優先度を付けて、段階的にリリースしていく。

7.2 コンウェイの法則

アーキテクチャは、それを作った「組織」のコミュニケーション構造を反映するが、組織の都合で出来たアーキテクチャは最適でない可能性が高い。

そのため、まずアーキテクチャを先に設計し、十分な検証の後、組織編成するのが最も効率的である。

7.3 割れた窓の法則

悪いコードは邪心を引き出す

コードに一箇所でも悪い部分があると、それを見た他のプログラマも適当なコードを書こうとしてしまう。

コードは清潔に保つ

悪い部分があったら放置せずにすぐ修正する。 万が一すぐの修正が難しい場合は、悪い部分を明示して、コードの管理が適切に行われていることのアピールをしておく。

7.4 エントロピーの法則

コードは無秩序へ向かう

仮に良いスタートを切ったとしても、徐々にコードの腐敗が進み、どんどん保守が難しくなっていく。

コード腐敗の兆候を掴む

硬さ

  • 変更の難しさ
  • 一つの変更で、それと依存関係のあるモジュールを連鎖的に変更しなければならないようなコード
  • 対策:モジュール間の無駄な依存関係を排除する

脆さ

  • たった一つの変更だけで他の部分が壊れてしまう度合い
  • 破損と修正を繰り返し続けるようなコード
  • 対策:

移植性のなさ

  • 他の環境への移植がしにくいこと
  • 「環境に依存している部分」を全体から切り離すのが難しい場合、移植性がないと言える
  • 対策:特定環境への依存性

扱いにくさ

  • コード

    • 設計構造に柔軟性がないこと
    • 設計を保持したまま、容易に機能の変更を行なうことが出来ない
    • 対策:設計に柔軟性を持たせる
  • 環境

    • 開発環境が非効率なこと
    • コンパイルが遅い」「ちょっとの変更でも全体をコンパイルし直さなければならない」など
    • 対策:なるべく高速な環境を選択する、コンパイル速度の低速化を招くようなことはしない

複雑さ

  • 不要な要素の存在
  • 「後で必要になりそうだから入れておく」→「結局使わない」という流れの中で、コードに無駄な構造が散乱し、理解しにくくなる
  • 対策: 不要な要素を記述しない

繰り返し

  • 同じ記述が何度も記述されていること
    • 変更時に複数の箇所に修正をしなければならない
    • 見落としから不具合の発生を招く可能性がある
  • 対策:関数化するなどして、一箇所の記述を使いまわす
    • 僅かに処理が違う場合は、抽象化してなるべく共通の部分だけを使いまわすこと

不透明さ

  • 分かりにくく処理が複雑なコードは、コードを書いた本人以外には理解し難いモノになりがち
  • 対策:読み手に理解してもらえるよう最大限配慮したコードにする、コードレビューをもらう
アジャイルで腐敗を許さない

アジャイル型の開発では、変化に柔軟に対応できる。

また、変化に適応できない初期設計にほとんど時間を割かないため、時間効率も良い。

チーム文化で腐敗を許さない

「常にシンプルに保つ」「過剰な設計をしない」などといったチームの行動指針で、腐敗を発見次第リファクタリングしていく。

7.5 80-10-10の法則

プログラミングに万能薬は無い

一つのツールでユーザーの要求を満たそうとすると、以下のようになる。

  • 80%:実現可能
  • 10%:実現は可能だが、相当な努力が必要
  • 10%:実現不可能
適材適所

ソフトウェア開発において、どんな場所にも適用できる万能なツールは存在しない。

そのため、ソフトウェアの仕様に最も適合しているツールを使用することが効果的。

7.6 ジョシュアツリーの法則

名前を知ることで存在を知る

物事や概念があっても、名前を知らなければ活用できない。そのため、まず名前を知ることが大事。

ユビキタス言語

チーム内で利用する独自の言語を作成し、認識を共有させる。

7.7 セカンドシステム症候群

2番目のリリースは機能過多

2番目にリリースするバージョンは、機能を盛り込み過ぎていて、プログラマの設計する最も危険なバージョンになる傾向がある。

慣れると「多機能主義」へ

最初のリリースでは、未知のことが多く、リスクの高さから慎重な設計をする。

しかし、2回目のリリースとなってくると、慣れや知識が増えたことによって、無駄に機能を盛り込み過ぎてしまいがち。

ユーザーを考える
  • ユーザーは誰なのか
  • 何を必要としているのか
  • 何を必要だと考えているのか
  • 何を望んでいるのか

以上を考えた上で、必要な機能だけを実装する。

また、これは2回目だけに限った話ではない。

7.8 車輪の再発明

既にあるのに作る

作りたいものを実現しているコードやライブラリが既に存在しているにもかかわらず、自分でコードを作成するのは工数的にも非効率である。

主な原因
  • 知らない

    • 使用できるリソースの存在を知らないため、新しくコードを記述してしまう
    • 対策:チーム内で既に求めている機能を持ったコードが存在しているか確認する
  • 作りたい

    • 自分で開発したいという、プログラマのエゴ
    • 対策:ユーザーの要求を満たすことを最優先に考えること
再発明が必要なとき

ビジネス目的

  • 外部のコードを利用すると、その部分に依存性が発生してしまい、内部のコードの修正も難しくなってくるため

学習目的

7.9ヤクの 毛刈り

本当の問題に辿り着けない

問題を一つずつ解決している間に、本来自分の求めていた問題を忘れてしまうこと

早々に切り上げる

なかなか問題を解決できないときは、本来の目的から逸れていないか確認する。万が一逸れているようであれば、作業を取りやめて他のやり方を選択する。

問題整理

ヤクの毛刈りに対応しなければならないとき、問題をメモなどに書き留めながら1つずつ丁寧に解決していくようにするのが良い。

書籍 プリンシプルオブプログラミング 第6章 まとめ

6章

手法 〜プログラマの道具箱〜

6.1 曳光弾

最終形にも残る「骨格コード」

対空砲の曳光弾のように、プログラミングでも挙動の軌跡を見えるように曳光弾を放つ。

プログラミングにおける曳光弾は、優先的に検証したい部分を先行的に実装すること。 本来の仕様より簡易なモノでも構わないので、実際の環境下で動作の確認をする。

曳光弾のメリット

実際の環境下で実装するため、精度の高いフィードバックを即座に得られる。

また、ソフトウェアを早いうちからユーザに見せられるため、早い段階からユーザのフィードバックを受けることができる。

プロトタイプとの違い

プロトタイプは、使い捨てのコードを繰り返し生成しながら学習し、曳光弾の前の下調べをすることが目的

6.2 契約による設計

「呼び出し側」と「呼び出される側」の取り決め

関数を呼び出す側は、関数に正しい引数を渡す責任がある。(事前条件)

また、関数側は正しい引数に基づいて、正しい処理を行なう責任がある。(事後条件)

この関係のように、双方で契約を結んでいると見なしてプログラミングすることを「契約による設計」という。

「思い違い」の早期発見

コードの正しさを保証できる

  • 要求されたことのみを実現するコード

コードをシンプルに出来る

  • 契約によって事前条件が満たされていると仮定できるため、余計な予測コードを書く必要がない

問題の早期発見が容易になる

  • 契約を果たせなくなった時点で、意図的にクラッシュさせることで問題の早期発見に繋がる
コメントとアサーションで契約

関数の契約内容をあらかじめコメントで伝えておくこと。

また、受け渡し前に「事前条件」「事後条件」の値が正確かチェックする。万が一不正確だったら、その時点でソフトウェアを停止させる。

トラッシュよりクラッシュ

コード実行中に想定できないことが起きたら、早めに停止させること。無理に続行させると、障害を抱えたコードが動き続けることになり、他の部分にも致命的な影響を与えかねない。

6.3 防御的プログラミング

かもしれないプログラミング

他の関数から不正な値を受け取るかもしれないという推測から、被害を受けないように防御的なコードを記述しておくこと。

外部ソースからの入力値チェック(想定内のエラー)

  • 入力値が適切な範囲内に収まっているか、文字列の長さが規定内かなどのチェック
  • 無効な入力を早い段階で検出して、エラー処理を適切に行なうようにする

関数の入力引数の値をチェック(想定外のエラー)

  • 別の関数から渡された入力引数のチェック
  • ここで不正な値を検出した場合、コードのにバグが存在していることになる
  • 不正な値を検出したら、即座に処理を停止
開発と運用の安全運転

「防御運転」によって、以下のようにプログラミングが安全になる。

開発中の安全運転

  • 不正を早めに検出できるため、場所の特定が容易になりデバッグ効率が上がる

運用中の安全運転

  • 不正を早めに対処することで、運用までに問題を持ち込まずに済むため、運用中の問題を防ぐことができる。
バリケート戦略

検証用のモジュールを用意し、必ずその部分を通さないと関数への値の引き渡しを行えないようにする。

「正当性」と「堅実性」

正当性

  • 不正確な値を返すくらいだったら何も返さない方がいいという考え方
  • 安全や命に関わるソフトウェアでは、事故を防ぐために重視される

堅実性

  • なるべく実行できるように手を尽くし、不正確な結果になっても実行が継続されるのであれば構わないという考え方
  • 一般向けのコンシューマソフトでは、こちらが重視される

6.4 ドッグフーディング

ソフトウェアの味見

開発者がユーザーになりきって、ソフトウェアを利用すること。以下のようなメリットがある。

  • 機能の使い勝手、過不足の発見
  • 使用する上での障害の発見

また、リリース後もサービス利用し続けて、サービスの便利さを証明する。

6.5 ラバーダッキング

説明するというデバッグ

プログラミングにおいて、問題を抱えている部分を誰かに説明すること。これにより、問題について思考を整理でき、自己解決できる可能性がある。

また、他人に説明するという名目上、暗黙の仮定を明確にする必要がある、 「説明ができなくなる部分」「ロジックとの整合が取れなくなった部分」に不具合箇所が潜んでいる可能性が高い。 まず、「順を追って内容を明確にする」ことが大事。

6.6 コンテキスト

コンテキスト:周りの状況や背景のこと

以下の側面から、コードを書く際にコンテキストを上手く組み込む。

コードの読み書きに利用

  • モジュールなどの各要素にコンテキストを明示することで、コードを読む際、それが何を意味しているかの説明

思考のツールとして利用

  • 物事の関係性を理解する手助けになる
会話や思考を迷子にしない

読み手にとって、コンテキストがあることで各要素同士の関係が明確になり、現在位置を見失わなくなる。

また、コードを読む際にまず「このコードは何を意味しているのか」を理解できるため、理解の効率が大幅に高まる。

達人になるためには

達人がどのように思考をしているか模倣する。コンテキストを認識して、問題のコンテキストを掘り下げ(絞り込み)、適切な対処を行えるように訓練をする。

書籍 プリンシプルオブプログラミング 第5章 まとめ

5章

習慣 〜プログラマのルーティーン〜

5.1 プログラマの三大美徳

怠慢

全体の労力を減らすための手間を惜しまない - とにかく人の作業量を減らし、機械に仕事をさせる

繰り返しの仕組み化

  • 手作業で行なっている部分を、コードを書いて自動化する(テストやビルドの自動化など)
    • 最も自動化の効果がある部分を見極めて実装すること
  • ドキュメントの作成も、フォーマットを作成して使いまわす
短気
  • コードの不具合に対する怒り
    • その怒りをコードの改善に向ける

問題を想定して行動する - ユーザからクレームが来そうな部分は、あらかじめ改善してしまう - 変更される部分とされない部分を見極め、分けて考えること - 変わらない部分をベースに、変更される部分は自由に変更できるようにする - ユーザで変更できるようにする

傲慢
  • 自信を持って、誰に見られても恥ずかしくないコードを書く
    • そのコードに対して、責任を持つ

人に見られても恥ずかしくない仕事をするプロ意識

  • 綺麗なコードを心掛ける
  • コードは機能ごとにモジュール化して管理
    • 管理しやすくなる
    • 他のソフトウェアで流用しやすくなる
総評:知識を使って、自分やチームの労力を減らすことに注力すること

5.2 ボーイズスカウトの法則

コードの腐敗を阻止する

コードは時間の経過と共に腐敗し、品質が低下しがちなので、それを阻止する

  • 「前よりも綺麗にする」ということをチーム全員で心掛けること
コミットする際は改良してから

リポジトリから取得した時よりコードを綺麗にしてからコミットする

  • 完璧は目指さないでもいい、少しでも綺麗にすること
急がば回れ

近道して品質を犠牲に、コストや時間を浮かせることは、結果的に無駄なコストの発生要因になるため、ある程度回り道をしてでも、品質を上げること

具体的には、以下のようなことは避けるべき。

ユニットテストの省略

  • 手作業のテストになるため、負債が膨らみ続ける

目的が違う既存システムの流用

  • 規模や機能が大きくなってくれば破綻し、結局作り直すハメになる

不適切なライブラリの放置

  • 大規模化に伴い、競合の発生や無駄な複雑化を招く

5.3 パフォーマンスチューニングの箴言

速いコードは割に合わない

コードを最適化し過剰に速くしても、コードとして大切なものを失うことに繋がる

可読性の低下

  • 最適化によってコードの処理が直接的なものでなくなり、意図を読み取るのが難しくなる。

品質の低下

  • コードの処理が複雑になると、理解されずにスルーされてしまう部分が発生し、新たな欠陥へと繋がる。

複雑化の増大

  • 最適化では、特殊なバックドアでモジュール間の連携を強めることで軽量化を実現する。そのため処理のフローが複雑になり、モジュール間で強い依存関係が構築されることで、移植性の低下も招く。

保守の阻害

  • 最適化によって、コードが読みづらく理解するのが難しくなると、保守が困難になる(追いかけなければならない部分が増える)

環境間の結合

  • 最適化は一つの環境に依存することが多く、別の環境で実行すると、かえって遅くなることもある

作業量の増大

  • 単純に最適化という作業が増える(上記のデメリットを抱えながらも)
「良いコード」を書く

最初から最適化されたコードではなく、単純な良いコードを書くことを意識する。その上で、必要に応じて最適化していくこと。

5.4 エゴレスプログラミング

エゴを捨てる
  • 自分のプライドやうぬぼれを捨て、チームで協力してコードを改善していく(お互いで積極的にコードレビューし合う)

よりよいものを作るという目的を忘れてはならない

エゴレスプログラミングの十戒(要約)
  • 自分も間違えることがあり、それを素直に受け止める
  • 書いたコードは自分自身ではない
  • 上には上がいる
  • 相談なしにコードは書き直さない(自分が正しいと思わないこと)
  • スキルが低い人にも謙虚に
  • 変わり続けることということは、今後もずっと起こる
  • 権威は地位ではなく、知識から
  • 信条に基づいて戦う、ただし負けは認める
  • 部屋に篭りきらない
  • 人には敬意を持ち、コードには厳しく接する

5.5 一歩ずつ少しずつ

「手堅い歩み」は効率的

小さな作業を一つずつ確実に行なう方が、結果的に効率が良い。

一度に複数やらない

複数の場所を同時に編集→実行すると、エラーの数が多くなることで原因解明が難しくなったり、ちょっとしたエラーに躓いてしまう可能性が高くなる。

機能の設計と同じよう、一つ一つの作業を細分化した上で、その中で以下に早く完成させられるかが作業の効率化において重要である。

思考も一歩ずつ着実に

ロジックを紐解くときも、いきなり1から10まで飛ばして考えない。

一つずつ着実にステップを踏み、各ステップを高速化することで、思考の高速化と高品質化を図れる。

論理的思考のコツ
  • 瞬時に答えを得られると思わない、分からなくても考え続けること
  • 考え始めて、すぐに答えに飛びつかない。思い込みを排除し、他の可能性も検討する
  • 既に考えたこと、結論の出たことを覚えておく。何度も同じことを考え直さない
    • 思考をアウトプットすることで、忘れにくくなったり、頭の中にある無駄な考えの整理も出来る
  • 基本は論理だが過去の経験などから来る直感も、時には大切
    • 但し直感のみで答えを導き出そうとせずに、最終的にはロジックで裏付けすること

5.6 TMTOWTDI

TMTOWTDI:やり方は一つでない

ツールの多様性は善

他人に使用してもらうAPIなどを作る際は、達成したい目標に対し手段を複数用意することで、利用者は複雑なコードを書かなくても済む。(例えば対応する言語を増やすなど)

作る側にとっては、より複雑になり時間もかかるが、APIのような複数の利用者がいるサービスの場合、使われる時間の方が長くなるため、全体を見れば効率化されたと言える。