$30 off During Our Annual Pro Sale. View Details »

Bugless Code

Bugless Code

Yunosuke Yamada

October 16, 2022
Tweet

More Decks by Yunosuke Yamada

Other Decks in Programming

Transcript

  1. バグを生みにくい実装
    2022/09/16

    山田悠之介

    View Slide

  2. 目次
    1. バグを未然に防ぐ
    2. 読みやすいコードを書く
    2

    View Slide

  3. 1. バグを未然に防ぐ
    3

    View Slide

  4. バグには種類がある
    バグはその発生原因によって分類ができます。
    『組込みソフトウェア開発における品質向上の勧め バグ管理手法編』

    は IPA による組込みソフトウェアについての文献ですが、

    Web アプリケーションにも共通する部分が多いです。
    この文献には「バグの区分」があります。

    今回は実装について触れます。
    4

    View Slide

  5. バグの区分(実装区分の一部)
    ロジックの誤り
    条件の誤り、演算の誤り、など
    インターフェースの誤り
    non null な引数に null を渡す、呼び出す関数を間違える、など
    タイミングの誤り
    処理を書く場所が違う
    エラーチェックの誤り
    エラーチェックをしない、後処理が適切でない
    機能の欠如
    仕様と実装が異なる 5

    View Slide

  6. バグの区分(実装区分の一部)
    防ぎやすいものと防ぎづらいものがあります
    機能の欠如
    実装者が既存仕様や既存実装、新規仕様を正確に理解する
    タイミングの誤り
    理解した処理の流れを正確にコードに落とし込む
    これらを防ぐのは属人的で、比較的難しいです。
    インターフェースの誤り
    例えば関数の型を厳密に付けることで、

    自分やその関数を利用する他の実装者もバグを防げます。 6

    View Slide

  7. 型について
    any
    は論外です
    ライブラリの型が
    any
    を含む場合そのまま使わない
    string
    は改善の余地があります
    日付 →
    Date
    URL →
    URL
    種類が有限 → Literal types
    種類は有限ではないが規則がある → Template literal types
    number
    も同様です
    7

    View Slide

  8. 「エラーチェックの誤り」
    JavaScript の例外は非検査例外なので例外処理を忘れがちです。
    例外を投げるのはやめましょう。

    以下のようにすることでエラーチェックを強制できます。
    type Data =

    | {

    value: Value;

    error: undefined;

    }

    | {

    value: undefined;

    error: Error;

    };

    8

    View Slide

  9. 「ロジックの誤り」
    簡単に防げるものもあります。
    ==
    ,
    !=
    ではなく
    ===
    ,
    !==
    を使う
    isNaN()
    ではなく
    Number.isNaN()
    を使う
    if 文の
    {}
    を省略しない
    デフォルトパラメータを使う
    x ?? y
    のような処理を何回も書くのは良くない
    返り値の型を書く
    コンポーネントは JSX スタイルで使う
    9

    View Slide

  10. 正規表現を避ける
    正規表現は強力ですが問題も多いです。
    正しいか分かりづらい
    パフォーマンスが悪くなることがある
    別の方法がある場合は避けたほうが良いです。
    数値形式の場合
    isNaN()
    を使えないか
    日付形式の場合は
    Date


    URL 形式は
    URL
    のコンストラクタでパースする
    startsWith
    ,
    includes
    ,
    endsWith
    などで代用できないか
    10

    View Slide

  11. Falsy に注意する
    特に
    ""
    に注意が必要です。
    新フォーム定義では Falsy な値によるバグがいくつか出ました。
    if(str)
    ではなく
    if(str !== undefined)

    if(str !== "")


    ではないか考え直しましょう。
    number
    の場合も
    NaN
    はダメだが
    0
    は OK か、など考えましょう。
    11

    View Slide

  12. 2. 読みやすいコードを書く
    12

    View Slide

  13. どんなに気をつけてもバグは生まれる
    1 人でどんなに気をつけてもバグる時はバグります。
    もし、あなたのコードがバグっていたとしても読みやすいコード、

    読みやすい PR ならレビューで発覚する可能性があります。
    もし、発覚せずにマージされたとしても読みやすければ将来調査、

    修正がしやすいです。
    もし、バグっていなかったとしても、今後何回も読まれます。

    読みやすければ将来の自分や他の開発者の生産性を上げます。

    (逆にそうでない場合、他人の生産性を下げることになります)
    13

    View Slide

  14. 読みやすいコードを書く
    読みやすい名前を付ける
    例えば
    id
    は分かりづらい
    コメントを書く
    オプショナル引数はどういう時に必要なのか
    処理の場合、なぜそうしたのか、

    逆になぜ別の方法にしなかったのか書く
    関数を分ける
    一度に 1 つのことをする
    pure な関数はテストしやすい
    14

    View Slide

  15. 読みやすいコードを書く
    読みやすいテストを書く
    テストは振る舞いの説明です
    コミットを分ける
    一度に 1 つのことをする
    これらの多くは『リーダブルコード』にも書かれています。
    15

    View Slide

  16. 無駄な処理をしない
    不必要な処理をしていると、それを読んだ人は

    「もっと簡単な方法があるのになぜそうしないのだろう」

    と考えてしまいます。
    必要十分な処理を書きましょう。
    三項演算子を減らす
    返り値を使わない場合
    map
    ではなく
    forEach
    useState
    ,
    useEffect
    を減らす
    state と effect は React のライフサイクルで特別なもの
    16

    View Slide

  17. ネストしない
    ネストしたコードは読みづらいです。
    early return する
    必要なら関数に切り出す
    三項演算子を使わない
    if 文のネストのほうがマシです
    コールバックを使わない
    then
    ではなく
    async
    ,
    await
    を使いましょう
    17

    View Slide

  18. 正解はない
    読みやすいコードを書くためのポイントは限りがないです。

    どのようなコードが読みやすいか、
    どうしたら自分のコードが分かりやすくなるか

    考える続ける必要があります。
    例えば PR を出す前にもっと良いやり方がないか何回も

    (1 回ではない)考えましょう。
    18

    View Slide

  19. 参考
    『組込みソフトウェア開発における品質向上の勧め バグ管理手法編』

    https://www.ipa.go.jp/sec/publish/tn12-005.html
    『リーダブルコード』
    『Airbnb JavaScript Style Guide』

    https://github.com/airbnb/javascript
    19

    View Slide