目次
■ソフトウェア設計とメンテナンス
2022.12.08 2024.03.05 約5分
この記事は2022年4月発売 『良いコード/悪いコードで学ぶ設計入門』を取り上げた connpass勉強会 を再編集し、記事化したものです。 |
ミノ駆動本こと『良いコード/悪いコードで学ぶ設計入門』は、発売わずか5ヶ月で7刷重版、発行部数2万超えを達成したベストセラーです。より成長させやすいコードの書き方と設計を学ぶ入門書として最適な本書を著者が解説します。
ミノ駆動と申します。僕は大手電気機器メーカーで十数年、組み込みや Windows ネイティブの開発をしてきました。3年前、Web 系に軸足を移し、昨年 READYFOR にジョインしました。現在は、アプリケーションアーキテクトとしてレガシーな Rails システムのリファクタリングや、拡張性向上の設計、システム設計全般に従事してます。
|
本書は初級〜中級向けに、変更容易性の設計手法を解説しています。僕は長年ソフトウェアの技術的負債と戦ってきましたが、組み込み系であろうと Web 系であろうと、負債の構造はだいたい同じ。だから僕が見てきた負債のほとんどは、本書でカバーできます。
変更容易性
仕様変更時、なるべくバグを埋め込まず、素早く正確にロジック変更できるかを指し示す度合いです。変更容易性が低いと、バグを埋め込みやすくなる、変更に何日もかかるなどの弊害が生じます。変更容易性の低いコードをレガシーコード、技術的負債と呼びます。 |
|
タイトルに『良いコード/悪いコード』とあるので、コーディングの本なのかと思うかもしれませんが、中心的に扱ってるのは、クラス設計です。
|
設計スキルは、初級から中級の間にとてつもなく大きな谷があるんですね。例えば、リファクタリングやドメイン駆動設計のところまで何の手助けもなく、たった一人で乗り越えるのはかなりつらいですよね。本書は初級と中級の間にかける橋のような役割ができればと考えています。
本書の背後には、いろいろな技術書のエッセンスがあります。より上位の技術を理解するために必要な考え方を学ぶことができるはずです。
本書は論理展開(なぜ問題なのか、なぜ解決するのか)を手厚く解説しています。理由がわかると、下記のようなメリットが生まれます。
① 再現性が高まる
再現性とは、同条件で同事象を再現できる度合いです。対処の仕方や、それが有効であるか理由を知っていれば、悪しきコードに遭遇した際、同じ方法ですぐに対応できるようになります。
② 応用が効くようになる
基礎がなっていないものを応用しようとすると、守られるべき基礎がすっぽ抜けて台無し になります。本書は理由を重厚に説明しているので、基礎固めになり、自分で応用・発展させていくことができます。
③ 技術選択の精度が高まる
設計にはコストがかかります。開発費も時間も有限なので、無限にコストはかけられません。設計の仕組みや理屈を理解していれば、設計的に妥当な判断ができるようになります。(銀の弾丸に陥らずに済む)
④ チームや上司に設計理由を説明できるようになる
設計リテラシーが高くないチームに新しい設計を導入する際、理由や効果を示して説得する必要があります。本書は理由を手厚く解説しているため、なぜそれを設計をすべきか?理由の知識を深める手助けになります。
以前の職場では「リファクタリングするかどうか?」で血みどろの戦いに。反対勢力を説得するため理論武装したときのノウハウなど本書には実践経験が豊富に詰め込まれています。
本書を読むときは、ぜひ Why の記述に着目してみてください。そして実際に手を動かしてみると、より Why への理解が進みます。泥臭い製品コードを題材に設計の練習をしてみましょう。*詳細は本書の17章をご覧ください。
書籍 『リファクタリング』や『レガシーコード改善ガイド』には、さまざまな設計テクニックが掲載されています。下記もそのテクニックのひとつ「メソッドの移動」です。
しかし、実際このとおりにリファクタリングしたとしても、設計が理解できていなければ、次にどのような行動をすれば良いのか、どう改善すればいいのかわからないはずです。
手法だけを表面的に真似ると、どうしても中途半端な設計に陥りがちなのです。もちろん熟読すれば理解はできるでしょうが、ものすごく骨の折れる作業です。それに対し本書籍3章では、クラス設計の基礎を徹底的に解説しています。本来のクラス設計のゴールは、決して不正状態に陥らない構造にすること。例えばマイナスの注文数やありえない金額になることを不正状態とするならば、常に正常なインスタンスのみが存在可能なその構造(自己防衛責務)を目指します。
全てをこの状態に持っていくのは困難でしょうが、本来システム全体の理想的なゴールはこの状態です。つまりクラス設計のゴールがわかる = 上位技術書のノウハウについて、より深く意味を理解できるようになる より活用できるようになる
本書は大部分においてエリック・エヴァンスのドメイン駆動設計(DDD)の影響を受けています。そのため本書を読むことで、DDDを実践するうえで必要な「基本的な考え方」を学べます。例えば 、ユビキタス言語というものがあります。これは意図や目的を共有する言葉で、ドメインモデルや境界付けられたコンテキストの設計に密接に関わります。
野菜炒めでしょうか。お供えものの精霊馬でしょうか。いずれにしても野菜を加工していることに違いはありません。つまり同じ言葉でも、目的によってその意味を変えるわけです。
ドメインモデルは更新(データの加工や変換)モデルです。ドメインモデルは、加工対象のデータやロジックをカプセル化します。
例えばECサイトで商品を売買する場合、在庫管理や配送など解決しなければならない問題はたくさんあります。こうしたあらゆる問題に、たったひとつの万能な商品モデルは成立するのでしょうか。
答えは「難しいし、あらゆる弊害が生じる」でしょう。
クソコード動画「一枚岩モデル」 #AWSDevDay pic.twitter.com/NwfOmXWy6F
— ミノ駆動 (@MinoDriven) November 9, 2022
|
従って、目的ごとにその特化したモデルを設計することがベストであるといえるでしょう。
各特化型モデルは、それぞれ適用可能な範囲が異なります。この範囲をシステム境界として定めたものが「境界付けられたコンテキスト」です。そもそもDRY原則は、コードの重複を許さないのではなく、意図や目的単位の重複を許さない原則です。DRY原則に従うのであれば、モデルの背後にある目的を認識できて初めてDRYにできるわけです。でも、その目的が曲者で、いつも背後に隠れてて本当に分かりにくいし認知困難です。「商品」という名前がついてると目的が隠れて見えないので認識困難になり、モデリングの品質も低下してしまう。下記のスライドのように、はじめから目的駆動で名前を設計するようにしましょう。
ここまで「目的駆動」なんて呼び方をしていますが、実はこれユビキタス言語の操り方を解説してるのです(ユビキタス言語を解釈しなおして整理したもの)。こんな感じで僕の本はDDD用語を使わずにDDDを解説している内容が随所にあります。
10章:名前設計・・・ユビキタス言語の操り方を解説
13章:モデリング・・・ドメインモデリングを解説
15章:設計の意義と設計への向き合い方・・・DDDの戦略面を解説
その他、さまざまな箇所にDDDエッセンスを散りばめています。つまりミノ駆動本を読めば DDDに必要な基礎を無理なく自然に身につけられるのです。
ソフトウェアアーキクチャとは
望まれる品質特性やその他の性質を促進するためにソフトウェアをどう構成するかということに対する、重要な設計判断が集まったもの、またこの設計判断を担う人。『Design It! – プログラマーのためのアーキテクティング入門』著 :Michael Keeling、訳:島田浩二、2019年 刊行、オライリージャパン、 p.8より引用
こちらの経産省の資料を見てください。フロントエンド、バックエンド、インフラ、幅広い分野をもつエンジニアリングの世界で、設計に興味を持ちアーキテクトを目指す人は、本当に少ないのです。僕の体感でも全体の1〜2割に満たない。
しかしアーキテクトキャリアは、このようにさまざまな利点があります。
ソフトウェアアーキテクトの仕事を書き出してみました。これらは私が普段の業務でやってることです。書籍では、ソフトウェアアーキテクトに必要な初歩の考え方をすべてカバーしているので、ぜひ読んでみてください。
ネットの反応見てるとリーダブルコードと比較されることが多いのですが、だいぶ違います!
▼リーダブルコード
命名やコードブロック整え方など、読みやすさを中心に解説 ▼ミノ駆動本 仕様変更時にバグを埋め込みにくくし、素早く変更できるようになるための構造設計を解説。10章名前設計では命名を取り扱っているが、読みやすさというより責務や構造定義のための手法として解説 |
いろいろな設計スキルを使ってモンスター(アンチパターン)を退治するゲームです。制作に4年かかりました。僕の書籍で取り上げているアンチパターンがモンスターとして出てきます。無料で遊べるのでぜひ!
僕が執筆した技術書『良いコード/悪いコードで学ぶ設計入門』。
こちらのバグ退治RPG『バグハンター2 REBOOT』が副教材的な位置付けになっております。ぜひお手にとって遊んでください。より理解が進むでしょう。
PC、スマホでプレイ可。無料です。https://t.co/XPv0gitEQq pic.twitter.com/wqabyZdpix
— ミノ駆動 (@MinoDriven) March 12, 2022
技術的負債による損失は、国内全体で国家予算に匹敵するレベルといわれています。IT成長のために負債解消は喫緊の課題です。しかし技術的負債そのものや解決方法としての設計は世の中的に認知が不十分。もっと認知度を高める必要があります。ぜひ1票を投じてください。
#Forkwell_Library
『良いコード/悪いコードで学ぶ設計入門』への1票、ぜひお願いいたします。 https://t.co/MWTLgVqH76— ミノ駆動 (@MinoDriven) November 22, 2022
ここからは視聴者からのQに回答します。本講演では過去最多となる58件もの質問が寄せられました。その中から、人気投票数の高いものをピックアップしお届けします。
ミノ駆動:僕は普段から Twitter でリファクタリングや設計関係のつぶやきが多いんですが、あるとき仕事が辛くて泣き言ばっかり投稿していたら、クラウドワークス社の役員から「うちのシステムの技術的負債をうまくリファクタリングできないか」と連絡があったんです。だから普段から技術発信していくことが結構大事かなと思ってて。必ず誰か見てくれてると思うんですよ。同じような悩みを持つ人に手を差し伸べることにもなるし、巡り巡って自分を助けることにもつながる。
— なるほど。組み込みならではの設計の考え方が生かされたことはありますか?
ミノ駆動:例えば、ドメイン駆動設計におけるリポジトリパターンは、すごく役に立ったかな。
僕が見てきた印象だと Web系エンジニアの皆さんは、データベースありきな気がしています。データベースは保存手段のひとつでしかない。例えば、組み込みの保存方法だと、フラッシュメモリに書き込む・ファイルに書き込む・業界独自の特殊なプロトコルで外部に転送する……いろいろありますが、保存のフォーマットは外の世界の話。要は自分たちが作ったアプリケーション世界の話じゃないんですよ。ドメインモデルをどう設計するかと、保存の話は全然別の世界の話。どう保存するか。保存の構造をどうするかに関してはリポジトリで疎にして、ピュアなドメインモデルを設計するという部分において組み込みの経験は役に立ったかなと思います。
— 畑違いの職種にチャレンジすることに不安はありませんでしたか?
ミノ駆動:今でも大変ですよ(笑)例えば、Rails は特殊なフレームワークに感じる。インフラまわりもいまだによくわかってないですよ。キャッチアップには苦労しています。
ミノ駆動:問題ないと思います。本記事で「目的ごとにその特化したモデルを設計する」と解説しましたが、コンテキストが違っても同じような属性が必要なときもありますよね。それは別に持ってて別に問題ないと思います。
— 実演は難しそうなので、ドメインモデルをもう少しわかりやすく解説いただくことはできますか?
ミノ駆動:例えば、本記事で紹介した審査品目を例にします。審査品目は、審査に関係するデータ(商品の内訳、審査結果など)と、そのデータを更新するロジックをカプセル化するんです。だから審査品目には、配送・注文などのデータやロジックは一切入らない。もし審査品目の中に、注文数などが入ってきたら混乱するじゃないですか。何か達成したい目的(審査したい・在庫管理したい・商品を配送したい)に、沿うような形で必要なものだけを集めてカプセル化するのが、ドメインモデルの作り方です。
— 「抽象的なクラスを作る → 機能追加を繰り返し神クラスができる → 責務ごとにクラスを分解する…というスタイルから抜け出せません」とあります。
ミノ駆動:システムが対象とする物事を細かく見分けられるようになりましょう。解像度を高めることが、クラスの巨大化を抑止する、適切な粒度でクラスを設計することに繋がります。いま「神クラスができる」理由は、(本記事「商品」を例にすると)商品の概念の細かな違い、見分けが付いていないから。僕はよく「見えない概念を探しにいく」というのですが、大抵わからない概念は隠れて見えないんです。だからどうするかというと、目的をつぶさに探していくんです。実は細かくゴールが違う。目的単位で分けていくんです。
— 「インプットは独学、 アウトプットは実際にアプリを設計、実装するのが良いでしょうか」とのことです。
ミノ駆動:それがいいと思います。僕も初めから設計スキルを持っていたのではなく、泥臭いプロダクションコードを使って裏でリファクタリングの練習をしていました。小さくてもクラスをちゃんと設計できれば、アーキテクチャの素養は身に付きます。
ミノ駆動:『現場で役立つシステム設計の原則 増田 亨』は一番手に手に取りやすく、ミノ駆動本と行ったり来たりしやすい。学びの相乗効果を狙えそうです。少しハードルを上げるなら『セキュア・バイ・デザイン』もいいかも。セキュリティ本でありながら、多要素認証でどうこうするのではなく、不正状態の混入防止という観点で解説していて、それについてドメイン駆動設計をベースに説明しています。ドメイン駆動設計を噛み砕いて説明しているのでわかりやすいし、ミノ駆動本と思想が似ているところがあって、読みやすいです。