Forkwell Press

SHARE

目次

目次

SHARE

『良いコード/悪いコードで学ぶ設計入門』を、一歩深める読み方 ミノ駆動本解説

ミノ駆動本解説

── 「つぎの一歩が見つかる、気づきと学びの場」 Forkwell Library シリーズ 第11回は、大ベストセラーであるミノ駆動本こと『良いコード/悪いコードで学ぶ設計入門』をピックアップ。2022年4月末に出版され、発売わずか5ヶ月で7刷重版、発行部数2万超えを達成。本書は、より成長させやすいコードの書き方と設計を学ぶ入門書です。

拙著『良いコード/悪いコードで学ぶ設計入門』は、変更容易性設計を主軸にノウハウを解説しており、より高いレベルを目指すための記述や、その背景思想が随所に散りばめられています。 本セッションでは、拙著の内容をより咀嚼し十二分に血肉とするための読み方や観点を解説します。躊躇してまだ読まれていない方にも、価値が伝わればと思います。

ミノ駆動と申します。僕は大手電気機器メーカーで十数年、組み込みや Windows ネイティブの開発をしてきました。3年前、Web 系に軸足を移し、昨年 READYFOR にジョインしました。現在は、アプリケーションアーキテクトとしてレガシーな Rails システムのリファクタリングや、拡張性向上の設計、システム設計全般に従事してます。

エンジニアのみなさん、こんなことにお困りではありませんか?

  • どこかのコードを変更すると別の箇所でバグが発生する
  • 変更の影響がありそうな箇所を、あちこち探し回らなければならない
  • コードを読んでるだけで日が暮れてしまった
  • 仕様変更やバグ修正に何日も費やしてしまった

でも何か問題なの?どう直せば良いの?

本書で、だいたいの技術的負債は解決します!

本書は初級〜中級向けに、変更容易性の設計手法を解説しています。僕は長年ソフトウェアの技術的負債と戦ってきましたが、組み込み系であろうと Web 系であろうと、負債の構造はだいたい同じ。だから僕が見てきた負債のほとんどは、本書でカバーできます。

【変更容易性とは?】仕様変更時、なるべくバグを埋め込まず、素早く正確にロジック変更できるかを指し示す度合いです。変更容易性が低いと、バグを埋め込みやすくなる、変更に何日もかかるなどの弊害が生じます。変更容易性の低いコードをレガシーコード、技術的負債と呼びます。

本書は、変更容易性の設計手法を解説する入門書です。

変更容易性を高める設計を解説 

  • バグを埋め込みにくく素早く正確にロジック変更できるようになる
  • 開発生産性が向上する
  • 400ページにわたる膨大なサンプルコード、事例を用いて解説
  • さまざまなケースに対応できるようになる

タイトルは『良いコード/悪いコード』だけど、クラス設計の本

タイトルに『良いコード/悪いコード』とあるので、コーディングの本なのかと思うかもしれませんが、中心的に扱ってるのは、クラス設計です。

  • 安全に変更にできるようになるためのクラス構造を解説
  • 構造とはインスタンス変数、メソッドのシグニチャ、分岐構造 etc… 
  • 構造を説明しようとするとロジック細部に至るため「コード」と銘打っている
deepen-good-code-bad-code-001

初級から中級の間にある、とてつもなく大きな谷

設計スキルは、初級から中級の間にとてつもなく大きな谷があるんですね。例えば、リファクタリングやドメイン駆動設計のところまで何の手助けもなく、たった一人で乗り越えるのはかなりつらいですよね。本書は初級と中級の間にかける橋のような役割ができればと考えています。

deepen-good-code-bad-code-003

本書の背後には、いろいろな技術書のエッセンスがあります。より上位の技術を理解するために必要な考え方を学ぶことができるはずです。

深める① 理由を説明できる力が身につく

本書は論理展開(なぜ問題なのか、なぜ解決するのか)を手厚く解説しています。理由がわかると、下記のようなメリットが生まれます。

① 再現性が高まる

再現性とは、同条件で同事象を再現できる度合いです。対処の仕方や、それが有効であるか理由を知っていれば、悪しきコードに遭遇した際、同じ方法ですぐに対応できるようになります。

② 応用が効くようになる

基礎がなっていないものを応用しようとすると、守られるべき基礎がすっぽ抜けて台無し になります。本書は理由を重厚に説明しているので、基礎固めになり、自分で応用・発展させていくことができます。

③ 技術選択の精度が高まる

設計にはコストがかかります。開発費も時間も有限なので、無限にコストはかけられません。設計の仕組みや理屈を理解していれば、設計的に妥当な判断ができるようになります。(銀の弾丸に陥らずに済む)

④ チームや上司に設計理由を説明できるようになる

設計リテラシーが高くないチームに新しい設計を導入する際、理由や効果を示して説得する必要があります。本書は理由を手厚く解説しているため、なぜそれを設計をすべきか?理由の知識を深める手助けになります。

以前の職場では「リファクタリングするかどうか?」で血みどろの戦いに。反対勢力を説得するため理論武装したときのノウハウなど本書には実践経験が豊富に詰め込まれています

Whyがわかると 開発上、さまざまな恩恵がある

本書を読むときは、ぜひ Why の記述に着目してみてください。そして実際に手を動かしてみると、より Why への理解が進みます。泥臭い製品コードを題材に設計の練習をしてみましょう。*詳細は本書の17章をご覧ください。

深める② 上位技術書をより深く学べる、活用できる

書籍 『リファクタリング』や『レガシーコード改善ガイド』には、さまざまな設計テクニックが掲載されています。下記もそのテクニックのひとつ「メソッドの移動」です。

deepen-good-code-bad-code-004

しかし、実際このとおりにリファクタリングしたとしても、設計が理解できていなければ、次にどのような行動をすれば良いのか、どう改善すればいいのかわからないはずです。

deepen-good-code-bad-code-005

手法だけを表面的に真似ると、どうしても中途半端な設計に陥りがちなのです。もちろん熟読すれば理解はできるでしょうが、ものすごく骨の折れる作業です。それに対し本書籍3章では、クラス設計の基礎を徹底的に解説しています。本来のクラス設計のゴールは、決して不正状態に陥らない構造にすること。例えばマイナスの注文数やありえない金額になることを不正状態とするならば、常に正常なインスタンスのみが存在可能なその構造(自己防衛責務)を目指します。

deepen-good-code-bad-code-006

deepen-good-code-bad-code-007

全てをこの状態に持っていくのは困難でしょうが、本来システム全体の理想的なゴールはこの状態です。つまりクラス設計のゴールがわかる = 上位技術書のノウハウについて、より深く意味を理解できるようになる より活用できるようになる

深める③ ドメイン駆動設計の理解が進む

本書は大部分においてエリック・エヴァンスのドメイン駆動設計(DDD)の影響を受けています。そのため本書を読むことで、DDDを実践するうえで必要な「基本的な考え方」を学べます。例えば 、ユビキタス言語というものがあります。これは意図や目的を共有する言葉で、ドメインモデルや境界付けられたコンテキストの設計に密接に関わります。

「野菜を加工する」と聞いて 何が思い浮かびますか?

野菜炒めでしょうか。お供えものの精霊馬でしょうか。いずれにしても野菜を加工していることに違いはありません。つまり同じ言葉でも、目的によってその意味を変えるわけです。

deepen-good-code-bad-code-008

ドメインモデルは更新(データの加工や変換)モデルです。ドメインモデルは、加工対象のデータやロジックをカプセル化します。

あらゆる問題に対応可能な「統一的な一枚岩モデル」は弊害が生じる

例えばECサイトで商品を売買する場合、在庫管理や配送など解決しなければならない問題はたくさんあります。こうしたあらゆる問題に、たったひとつの万能な商品モデルは成立するのでしょうか。

deepen-good-code-bad-code-009

答えは「難しいし、あらゆる弊害が生じる」でしょう。

統一的な一枚岩モデルにより生じる弊害を書き出してみた

・どの状況で何のデータが使われるのか分かりにくくなる

・どの状況でどんな振る舞いが期待されるのか分かりにくくなる

 ・状況によって守るべき不変条件が異なる

・言葉やデータの意味が多義的になり、混乱をきたす 

 ・混乱によりエンバグしやすい

 ・データのフォーマットが状況によって違うケースもある

多くのあらゆるロジックと密結合になる

 ・保守や仕様変更時の影響範囲分析に莫大な労力を要する

従って、目的ごとにその特化したモデルを設計することがベストであるといえるでしょう。

deepen-good-code-bad-code-010

各特化型モデルは、それぞれ適用可能な範囲が異なります。この範囲をシステム境界として定めたものが「境界付けられたコンテキスト」です。そもそもDRY原則は、コードの重複を許さないのではなく、意図や目的単位の重複を許さない原則です。DRY原則に従うのであれば、モデルの背後にある目的を認識できて初めてDRYにできるわけです。でも、その目的が曲者で、いつも背後に隠れてて本当に分かりにくいし認知困難です。「商品」という名前がついてると目的が隠れて見えないので認識困難になり、モデリングの品質も低下してしまう。下記のスライドのように、はじめから目的駆動で名前を設計するようにしましょう。

deepen-good-code-bad-code-011

ここまで「目的駆動」なんて呼び方をしていますが、実はこれユビキタス言語の操り方を解説してるのです(ユビキタス言語を解釈しなおして整理したもの)。こんな感じで僕の本はDDD用語を使わずにDDDを解説している内容が随所にあります。

10章:名前設計・・・ユビキタス言語の操り方を解説

13章:モデリング・・・ドメインモデリングを解説

15章:設計の意義と設計への向き合い方・・・DDDの戦略面を解説

その他、さまざまな箇所にDDDエッセンスを散りばめています。つまりミノ駆動本を読めば DDDに必要な基礎を無理なく自然に身につけられるのです。

深める④ アーキテクトとしての第一歩

ソフトウェアアーキクチャとは

望まれる品質特性やその他の性質を促進するためにソフトウェアをどう構成するかということに対する、重要な設計判断が集まったもの、またこの設計判断を担う人。『Design It! – プログラマーのためのアーキテクティング入門』著 :Michael Keeling、訳:島田浩二、2019年 刊行、オライリージャパン、 p.8より引用

アーキテクト、深刻な人手不足

こちらの経産省の資料を見てください。フロントエンド、バックエンド、インフラ、幅広い分野をもつエンジニアリングの世界で、設計に興味を持ちアーキテクトを目指す人は、本当に少ないのです。僕の体感でも全体の1〜2割に満たない。

deepen-good-code-bad-code-012

しかしアーキテクトキャリアは、このようにさまざまな利点があります。

deepen-good-code-bad-code-013

ソフトウェアアーキテクトの仕事を書き出してみました。これらは私が普段の業務でやってることです。書籍では、ソフトウェアアーキテクトに必要な初歩の考え方をすべてカバーしているので、ぜひ読んでみてください。

deepen-good-code-bad-code-014

 

ちょっとおまけ① 『リーダブルコード』との差異

ネットの反応見てるとリーダブルコードと比較されることが多いのですが、だいぶ違います!

▼リーダブルコード

命名やコードブロック􏰀整え方など、読みやすさを中心に解説

▼ミノ駆動本

仕様変更時にバグを埋め込みにくくし、素早く変更できるようになるための構造設計を解説。10章名前設計では命名を取り扱っているが、読みやすさというより責務や構造定義のための手法として解説

ちょっとおまけ② バグハンター2 REBOOT

いろいろな設計スキルを使ってモンスター(アンチパターン)を退治するゲームです。制作に4年かかりました。僕の書籍で取り上げているアンチパターンがモンスターとして出てきます。無料で遊べるのでぜひ!

ちょっとおまけ③ ITエンジニアがみんなで選ぶ今年のおすすめ本!

技術的負債による損失は、国内全体で国家予算に匹敵するレベルといわれています。IT成長のために負債解消は喫緊の課題です。しかし技術的負債そのものや解決方法としての設計は世の中的に認知が不十分。もっと認知度を高める必要があります。ぜひ1票を投じてください。

ここからは視聴者からのQに回答します。本講演では過去最多となる58件もの質問が寄せられました。その中から、人気投票数の高いものをピックアップしお届けします。

Q:組み込みからWeb系に転身したきっかけは?

ミノ駆動僕は普段から Twitter でリファクタリングや設計関係のつぶやきが多いんですが、あるとき仕事が辛くて泣き言ばっかり投稿していたら、クラウドワークス社の役員から「うちのシステムの技術的負債をうまくリファクタリングできないか」と連絡があったんです。だから普段から技術発信していくことが結構大事かなと思ってて。必ず誰か見てくれてると思うんですよ。同じような悩みを持つ人に手を差し伸べることにもなるし、巡り巡って自分を助けることにもつながる。

— なるほど。組み込みならではの設計の考え方が生かされたことはありますか?

ミノ駆動例えば、ドメイン駆動設計におけるリポジトリパターンは、すごく役に立ったかな。

僕が見てきた印象だと Web系エンジニアの皆さんは、データベースありきな気がしています。データベースは保存手段のひとつでしかない。例えば、組み込みの保存方法だと、フラッシュメモリに書き込む・ファイルに書き込む・業界独自の特殊なプロトコルで外部に転送する……いろいろありますが、保存のフォーマットは外の世界の話。要は自分たちが作ったアプリケーション世界の話じゃないんですよ。ドメインモデルをどう設計するかと、保存の話は全然別の世界の話。どう保存するか。保存の構造をどうするかに関してはリポジトリでにして、ピュアなドメインモデルを設計するという部分において組み込みの経験は役に立ったかなと思います。

— 畑違いの職種にチャレンジすることに不安はありませんでしたか?

ミノ駆動今でも大変ですよ(笑)例えば、Rails は特殊なフレームワークに感じる。インフラまわりもいまだによくわかってないですよ。キャッチアップには苦労しています。

Q:目的毎にモデルを分けた結果、それぞれのモデルにプロパティが重複するのは問題ないですか?

ミノ駆動問題ないと思います。本記事で「目的ごとにその特化したモデルを設計する」と解説しましたが、コンテキストが違っても同じような属性が必要なときもありますよね。それは別に持ってて別に問題ないと思います。

Q:ドメインモデルが図に起こされる様子を見たいです。

— 実演は難しそうなので、ドメインモデルをもう少しわかりやすく解説いただくことはできますか?

ミノ駆動例えば、本記事で紹介した審査品目を例にします。審査品目は、審査に関係するデータ(商品の内訳、審査結果など)と、そのデータを更新するロジックをカプセル化するんです。だから審査品目には、配送・注文などのデータやロジックは一切入らない。もし審査品目の中に、注文数などが入ってきたら混乱するじゃないですか。何か達成したい目的(審査したい・在庫管理したい・商品を配送したい)に、沿うような形で必要なものだけを集めてカプセル化するのが、ドメインモデルの作り方です。

deepen-good-code-bad-code-011

Q:自身のコーディングスタイルから一歩成長するためには?

— 「抽象的なクラスを作る → 機能追加を繰り返し神クラスができる → 責務ごとにクラスを分解する…というスタイルから抜け出せません」とあります。

ミノ駆動システムが対象とする物事を細かく見分けられるようになりましょう。解像度を高めることが、クラスの巨大化を抑止する、適切な粒度でクラスを設計することに繋がります。いま「神クラスができる」理由は、(本記事「商品」を例にすると)商品の概念の細かな違い、見分けが付いていないから。僕はよく「見えない概念を探しにいく」というのですが、大抵わからない概念は隠れて見えないんです。だからどうするかというと、目的をつぶさに探していくんです。実は細かくゴールが違う。目的単位で分けていくんです。

Q:アーキテクトを目指すための学習方法は?

— 「インプットは独学、 アウトプットは実際にアプリを設計、実装するのが良いでしょうか」とのことです。

ミノ駆動それがいいと思います。僕も初めから設計スキルを持っていたのではなく、泥臭いプロダクションコードを使って裏でリファクタリングの練習をしていました。小さくてもクラスをちゃんと設計できれば、アーキテクチャの素養は身に付きます。

Q:ミノ駆動本の次に読むべき “おすすめの1冊” は?

ミノ駆動『現場で役立つシステム設計の原則 増田 亨』は一番手に手に取りやすく、ミノ駆動本と行ったり来たりしやすい。学びの相乗効果を狙えそうです。少しハードルを上げるなら『セキュア・バイ・デザイン』もいいかも。セキュリティ本でありながら、多要素認証でどうこうするのではなく、不正状態の混入防止という観点で解説していて、それについてドメイン駆動設計をベースに説明しています。ドメイン駆動設計を噛み砕いて説明しているのでわかりやすいし、ミノ駆動本と思想が似ているところがあって、読みやすいです。

登壇者紹介

ミノ駆動

READYFOR株式会社 / システム基盤部 エンジニア

システムのリファクタリングや拡張性向上設計など、設計全般を推進。 著書『良いコード/悪いコードで学ぶ設計入門』は発売5ヶ月で7刷の重版、2万部超えを達成。Developers Summit 2021 Summerベストスピーカー賞3位。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ForlkwellPress ロゴ画像

編集部

Follow

エンジニアに役立つ情報を定期的にお届けします。

エンジニアに役立つ情報を定期的にお届けします。