2024年04月21日
ソフトウェア開発で、こんな経験はありませんか。
- どこかのコードを変更すると、別の箇所でバグが発生した。
- コードを読んでいるだけで日が暮れてしまった。
- コードを読んでいるだけで日が暮れてしまった。
- 簡単だと思っていた仕様変更やバグ修正に何日も費やしてしまった。
巷であの有名なリーダブル・コードに並ぶ名著とされる「良いコード/悪いコードで学ぶ設計入門」を読んだ。
リーダブル・コードは「コーディング」という行為そのものに対して焦点を当てた本だったと思うが、本書はタイトルの通り「設計」にフォーカスを当てている。と、書き出してみたのはいいものの、そもそも「コーディング」と「設計」の違いっていったいどのあたりにあるのだろう。このような疑問を感じた時は生成AIに聞いてみる。
コーディングは、ソフトウェア開発のプロセスにおいて、具体的なプログラム言語を用いて、アルゴリズムや機能をコンピュータが理解できる形に翻訳する行為です。コードを書くことは、設計されたソフトウェアの設計図を基に、それを具体的な形にする工程と言えます。リーダブル・コードは、このコードが読みやすく、効率的で、バグが少ないようにどのように書くべきかに焦点を当てています。
一方で、設計はもっと抽象的な段階で行われます。ここでは、ソフトウェアがどのような機能を持つべきか、それらの機能がどのように連携するか、どのようなデータ構造やアルゴリズムが必要かということを考えます。設計は、ソフトウェアのアーキテクチャを構築するプロセスであり、良い設計はシステムの拡張性、メンテナンス性、効率性を大きく左右します。
分かるような気がする。
本書はまさに後者の通り、「それらの機能がどのように連携するか、どのようなデータ構造やアルゴリズムが必要か」ということについて述べられている。コードの書き方の例も一部あるが、どちらかというとどうロジックを分離するか、どう責任を持たせるか、どういう名前にするか、などが中心に語られる。
職業プログラマーではないので、あまり大規模な設計に出くわしたことがないのだが、参考になる場面が多かった。
アンチパターンとして単一のクラスに責任を負わせすぎる話があった。
一つのクラスに詰め込むまくる、ということは自分も良くやりがちなので、耳に痛い思いもする。
例えば単一責任の原則にのっとり、クラスが巨大化する名前について警鐘を鳴らしている。
クラスの巨大化複雑化を誘発する名前が存在します。
この事態を招く代表的な名前にManagerがありあmす。ゲームを開発する架空の状況を例に説明します。
開発初期に、ゲーム内のメンバーを一元管理するMemberManagerクラスが作られました。MemberManagerの各メソッドを使えば、メンバーのパラメーターを取得したり変更したりできるものです。管理する種子から、メンバーに関するあらゆるデータはすべてMemberManagerが保有するつくりとします。
Class MemberManage { // メンバーのヒットポイントを取得する。 int getHitPoint(int memberId){...} // メンバーの魔法力を取得する。 int getMagicPoint(int memberId){...} }
開発が進み、歩行アニメーションを実装する段階にきました。MemberManagerはメンバーに関するあらゆるデータを保有するつくりです。…
引用を一部で止めたがこの後は想像の通りである。MemberManagerクラスはどんどん肥大化していき、メンテナンスが困難になっていく。なぜこのようなことが起きるというと、「管理」という意味が広いあいまいな言葉に悪魔が潜んでいると筆者は指摘している。
例えばECサイトを運営しているとして、「商品」という言葉が出てくる。この「商品」という言葉も曖昧で「発送品」、「配予約品」、「在庫品」、「注文品」など、目的に特化した命名をするべきである、という話もある。
こういう発想をしたことがそもそもないので、目から鱗が落ちる思いだった。
ちなみに筆者は有名なクソコード動画の作者であるらしい。
クソコード動画「Managerクラス」#すえなみチャンス暑気払い pic.twitter.com/3FSQDkXfHu
— ミノ駆動 (@MinoDriven) August 3, 2019
題材がJavaで自分にとっては不慣れな言語であるが読み物としても面白い。ECサイトやゲームのRPGを題材にしているので、言語に習熟していなくても、アンチパターンとデザインパターンのイメージがしやすい。手元に置いて、定期的に読み返したいタイプの本だと思う。