HapInS Developers Blog

HapInSが提供するエンジニアリングの情報サイト

今、再確認したい「関数の分割」のメリットと目安

サンシャイン山田です🌄

HapInSアドベントカレンダー2024 1日目の記事です!

昨年に引き続き、HapInSアドベントカレンダーをやろうということで、企画させていただきました!

今年も毎日投稿する予定ですので、ご期待ください!

そしてHapInSの執筆者の皆さん、頑張りましょう🔥

対象とする読者

  • プログラミング初心者の方

  • 初心者ではないが、10年後もエンジニアを続けるためのテクニックを模索中の方

関数が長くなってしまうこと、ありませんか

さっそく本題ですが、僕はよくあります。

可読性に気を付けてコーディングしているはずなのに、たまに振り返ってみると長くて、複雑で、読みにくい…

(もちろん、仕方ない場面などもあるとは思いますが)

これを回避するため、複雑な関数をタスクごとに分解し、それぞれを別の関数にする作業をすると思います。

この作業が、生成AIの登場でさらに重要になってきたと思ったので、今回はそのメリットと目安を調査してみました。

ぜひご覧ください。

「関数の分割」のメリット

生成AIの登場で追加されたメリット

  1. 生成AIに質問しやすい:プログラミングに関わらず、単純な質問に分けて生成AIに聞いた方が良い答えが返ってきますよね。

  2. 学習されたくない部分を分離できる:AIに食わせたくない重要なロジックや情報を、プロンプトに書かなくて済みます。

  3. リファクタリングしてほしくないロジックを守れる:もういじってほしくない部分もあると思います。

既存のメリット

  1. 可読性が向上:他人はもちろん、未来の自分が読みやすいコードに。

  2. テストが作成しやすい:関数ごとの責任が明確な方が、単体テストが作成しやすいと言われています。

  3. 継続的なリファクタリングがしやすい:単体テスト(自動テスト)がしっかり整備されていれば、デグレは怖くありません。また、可読性が高いということは、未来の担当者の生産性も上がります。

「関数の分割」の目安

次に、分割の方針となりそうなことを紹介します。

コマンド・クエリ分離の原則(CQS)

全ての関数は、コマンドかクエリのどちらか片方でなければならないという考え方です。

  • コマンド:データを追加/変更し、戻り値がない関数

  • クエリ:データを追加/変更せず、戻り値がある関数

データを変更しつつ、戻り値もある関数があったら、分割の余地があると言えます。

カプセル化

例えば以下の2つの関数は、まとめて1つの関数に隠ぺいした方が良いかもしれません。

  • 残高 > 1万円を確認する処理

  • 残高 - 1万円する処理

呼び出し側で考慮することを減らせます。他にもバリデーションなどがこれにあたります。

トランザクションごとに区切る

トランザクションも、間に余計なことを書かれないようにまとめておいていいと思います。ただしトランザクションの関数の中では、前述のCQSを守ります。

おわりに

いろいろ書きましたが、実は僕や僕の周りでは、生成AIとの協働はまだ根付いていません。(そんな人が、実際にはまだまだ多いんじゃないかと思います。)

そのため、AIをゴリゴリに使っているプロジェクトに入っても馴染めるように、かつ、今日から実践できるようなことを提案したいと思い、このテーマを選択しました。

これからも「人にもAIにもやさしいコード」を模索していきたいと思います。

どちらにもやさしいコードは実在する!