LINEヤフー Tech Blog で公開している「コード品質向上のテクニック」のポスト一覧です。
回 | タイトルとリンク | 一言まとめ | キーワード |
---|---|---|---|
68 | 諸刃のテスト | テストで過剰にロジックを注入してしまうと、テストが複雑になり、挙動の差異が隠れてしまう可能性がある。 | unit test , test double , injection |
67 | 過ぎたるエラーは猶及ばざるが如し | 複数のエラー表現を単一のエラー表現に統合することで、呼び出し元での取り扱いを統一する。 | error , model conversion , abstraction |
66 | アサートあっても憂いあり | 値の検証はオブジェクトの作成時や状態の更新時に行い、可能ならば、失敗時のハンドリングを呼び出し元に強制する形にするのが望ましい。 | validation , data model , type checking |
65 | Collection は List だけにして成らず | コレクションを使うときは、特徴の違いを意識して適切な種類を選択するべき。 | collection , implicit relationship |
64 | プライマリコンストラクタはシンプルにする | プライマリコンストラクタ内でパースや変換といった処理を行わない。代わりにセカンダリコンストラクタやファクトリ関数を実装する。 | constructor , factory function , data class |
63 | 値の裏切り | データの不整合のリスクを避けるために、重複データは使用する直前に作成すべき。 | data model , orthogonal relationship , collection , index |
62 | 二匹目の close |
遷移済みのときに例外を投げる代わりに、何もしないという動作にすることで、コードを頑健にできる可能性がある。 | idempotency , state transition , error handling |
61 | 悪いな、この関数 1 人用なんだ | 関数呼び出しの状態を必要とするときは、個々の呼び出しを区別できるようにする。 | instance state , call state , re-entrancy |
60 | 出る杭を「ひっぱたく」な | メインのロジックの抽象度は、サブのロジックよりも下げた方がよい場合もある。 | abstraction level , function , extraction |
59 | class の facade に水 | クラスの責任範囲を決めるときは、呼び出し側から見てインターフェースが単純かどうかを意識する。 | interface , encapsulation , single responsibility principle |
58 | 言葉にできない | 暗黙の期待が必要な場合、その期待の関係を関数/クラス/モジュールに閉じ込める。 | implicit expectation , dependency , encapsulation |
57 | 百見は一 fetch にしかず | コードレビューをするときは、変更そのものだけでなく周辺のコードも確認する。 | code review , code change , diff checkout |
56 | 期待八分目 | expected value を抽象化する。依存先のコードが複雑ならば、テストダブルのモックの作成を検討する。 | test double , mock , expected value |
55 | デメテルを知っているか | デメテルの法則を表面的に適用するのではなく、知識の境界を意識する。 | Law of Demeter , information hiding , encapsulation |
54 | 沈黙は金メッキかも | 警告はまず原因の解決を試み、抑制が必要なら範囲を限定した上でコメントを書く。 | warning , suppression , comment |
53 | 通知多くして関数山に登る | 1 つの関数につき、非同期処理の仕組みは 1 つに絞る。 | asynchronous , coroutine , callback |
52 | 分岐を伐り根を枯らす | 条件分岐の重複を避けるよりも、スコープを小さくすることを優先したほうがよいことが多い。 | conditional branch , completeness , extraction |
51 | 確信的な質問 | レビューコメントを書く際は、それが要求、提案、質問のどれに相当するかを考える。 | code review , review comment , communication |
50 | たった一つの真実 | 集約やコンポジションを適用するときは、値の重複による不正な状態に気をつける。 | aggregation , value domain , property duplication |
49 | 虚実皮膜の依存 | 型としての依存関係とオブジェクトとしての依存関係の違いを意識する。 | dependency , aggregation , object reference |
48 | ワイルドすぎる引数 | 複数の意味で解釈できるような汎用的すぎる引数の定義を避ける。 | parameter , semantics , flexibility |
47 | 不履行権の不履行 | デフォルトパラメータに使う値は、共通して使われる「普通の」値であるべきで、特殊な値は使うべきでない。 | default parameter , null object , special value |
46 | 関数は見かけによらず | 似たような名前を使って定義するときは、名前の差異と仕様の差異をできる限り一致させる。 | naming , consistency , principle of least astonishment |
45 | 終わり null ならすべてよし? |
コレクションやラッパーを作る場合は、エラー/エッジケースを示す型と値の型の重複に気をつける。 | null , empty , collection |
44 | 貧血の誤診 | ロジックとデータをまとめることを目的化せず、依存の方向を守る。 | dependency direction , data model , anemic domain model |
43 | 値の帰還 | 戻り値を決めるコードは、一ヶ所にまとめた方が良いときもある。 | return value , function responsibility , specification knowledge |
42 | テスト上の空論 | テストやランタイムアサーションの代わりに、静的検証を使うことを選択肢に入れる。 | static analysis , test , runtime assertion |
41 | 「アーキテクチャ」ただいま工事中 | テストは現在のコードだけでなく、将来の変更にも対応できるとよい。 | test , completeness , specification update |
40 | 三関数寄れば文殊の知恵? | 仕様に関する知識を一か所にまとめることを意識する。 | specification knowledge , implicit assumption , extraction |
39 | 作業の前に連絡を | 動作の順序を明確にするために、引数と戻り値を効果的に使う。 | implicit dependency , function flow , strength |
38 | マスターキーは何処 | キーやインデックスによる、要素同士の暗黙的な関係を避ける。 | key , collection , implicit relationship |
37 | 長いライフサイクルに巻かれる | ライフサイクルが異なるものを管理するときは、クラスを分けることを考慮する。 | disposable instance , cyclic state , state lifecycle |
36 | 「トートロジーはトートロジー」はトートロジー | コードを抽出したときは、情報量が増えるような名前を与えることを考慮する。 | naming , abstraction , extraction |
35 | 引数の持ち腐れ | 一部の条件でのみ使われる引数を作らないようにする。 | argument , orthogonal relationship , sum type |
34 | 三十六計分けるに如かず | どのロジックを使うのかが静的に決まる場合は、Strategy pattern の使用を避ける。 | strategy pattern , conditional branch , sealed class |
33 | シェフの気まぐれデコレーション | Decorator pattern を使うときは、その条件を確認する。 | decorator pattern , type checking , data model |
32 | 奈落からの帰還 | 早期リターンを使う場合は、その存在と条件、およびハッピーパスを目立たせる。 | early return , conditional branch , function flow |
31 | 同じ釜のプロパティ | 直和型に共通するプロパティを抽出することで、より分かりやすい構造にできることがある。 | sum type , sealed class , common property |
30 | 運命の赤い糸 (透明) | 関数の間に暗黙の関連性がある場合、関数を 1 つにまとめたり、関連性が明らかな実装に変えたりする。 | conditional branch , function precondition , implicit dependency |
29 | ゴルディアスの変数 | データの依存関係が複雑なときは、理想的な中間データを作ることで整理できる可能性がある。 | data dependency , function flow , intermediate data structure |
28 | 制約にも相続税 | 不変性を保証したい場合、継承不能にしたほうがよい。 | immutability , inheritance , override |
27 | 依存も積もれば | 依存性の注入を行うときは、その目的を明確にする。 | dependency injection , dependency explicitness , constructor parameter |
26 | 説明の計は一文目にあり | コメントを書くときは、最初に説明する内容を注意深く選ぶ。 | comment , documentation , short summary |
25 | TL;DR: つまり...どういうこと | レビューコメントでは、最初に提案や要求を書き、理由はその後で補足する。 | code review , review comment , explanation order |
24 | 遺産の価値 | 値が違うだけでロジックが同じときは、継承を使わずに、値の異なるインスタンスを作る。 | inheritance , instantiation , dynamic dispatch |
23 | return の切れ目が edge case の切れ目 | 早期リターンを使う前に、エラーケースと通常ケースを統合できないかを考える。 | early return , error case , function flow |
22 | To equal, or not to equal | equals が同一性 (identity) と等価性/同値性 (equivalence) のどちらを示しているのかを明確にする。 |
identity , equivalence , equals |
21 | コンストラクタを叩いて渡る | 準備できていないインスタンスは使えないようにする。 | initialization , constructor , factory |
20 | 異例の過剰包装 | 例外処理中に例外が発生した場合、どちらを優先するべきかを検討する。 | exception , error handling , wrapper |
19 | チャイルドロック | オーバーライド可能な範囲はできる限り制限する。 | override , super , inheritance |
18 | 関数を見て関係を見ず | 抽出を行う際は、「コードが何をするか」の意味のまとまりに注意する。 | extraction , boundaries of concept , nested loop |
17 | 砂上の楼閣 | ビルダーパターンの代わりにコンストラクタやファクトリ関数を使うことを考慮する | naming , grammar , attributive phrase |
16 | 火の null 所に煙は立た null |
エラーの値を区別する必要がある場合は、Null Object パターンを使わないほうがよいことが多い。 | error value , type checking , null object pattern |
15 | 文法は名を表す | 命名をするときは、宣言・定義側の一貫性よりも、使う側での誤解のされにくさに着目する。 | naming , grammar , attributive phrase |
14 | 責任を課すというたった一つの責任 | 責任の分割によって依存関係が複雑になることがある点に注意する。 | single responsibility , dependency , implicit constraints |
13 | クローン家族 | 2つの継承ツリー間での暗黙の対応関係を避けるために、継承をコンポジションや集約に置き換えたり、パラメトリック多相を利用する。 | type checking , inheritance tree , implicit correspondence |
12 | セット割引 | 状態の更新タイミングや値の組み合わせを制限するインターフェースを用意したほうがよい場合がある。 | mutability , updating interface , state object |
11 | 関数にたこができる | レシーバの状態を確認するコードは、そのレシーバの関数内で実行したほうが良い場合もある。 | state check logic , responsibility , implicit precondition |
10 | 起きば浮世の壱を見ん | 別のレイヤの詳細な動作に、暗黙的に依存するコードは避けるべき。 | implicit dependency , module structure , responsibility |
9 | 来た道を戻れ | 双方向の変換を行う場合、一方の変換ロジックからもう一方のロジックを演繹的に求めるのが好ましい。 | type conversion , bidirectional , single source of truth |
8 | 実像と虚像 | 関数の戻り値について、取得後に変化しうるかどうかを明確にする。 | view of collection , copied value , mutability |
7 | 新事成語 | 新しい要素を追加したときは、既存コードの名前の変更を検討する。 | naming , new element , inclusive relation |
6 | 乱切りか角切りか | コードの改行を行う際は、意味の区切りを意識する。 | line-break , code chunk , operator precedence |
5 | 悪列挙は良層を駆逐する | 外部で定義された値を変換するコードでは、内部の値と外部の値を互いに独立させて定義する。 | value conversion , externally defined value , enum |
4 | ドア破壊テスト | ユニットテストでは、内部的な動作についてよりも、仕様にあった振る舞いをしているかを確認するほうが好ましい。 | unit test , dependency , specification |
3 | 戦略なき戦略 | ループ中に大きな条件分岐がある場合は、分岐とロジックの対応付けがわかりやすい構造に書き換えることを考慮する。 | loop , conditional branch , strategy pattern |
2 | 確認したかどうか確認した? | 「チェック済みである」ことを暗黙的に前提にしたコードは、できる限り避けたほうが良い。 | implicit dependency , state check logic , type checking |
1 | 覆<error>盆に返らず | エラーがどの程度回復可能かに応じて、適切なエラーの表現方法を使う。 | recoverable error , logic error , exception |