『モノリスからマイクロサービスへ―モノリスを進化させる実践移行ガイド』

翻訳を担当した書籍『モノリスからマイクロサービスへ ―モノリスを進化させる実践移行ガイド』(オライリー・ジャパン)が12月26日に発売になります。本書は2019年11月にO'Reilly Mediaより出版されたSam Newman著『Monolith to Microservices: Evolutionary Patterns to Transform Your Monolith』の全訳で、マイクロサービスアーキテクチャを解説した書籍として日本でも定評のある『マイクロサービスアーキテクチャ』(原題『Building Microservices』)の著者であるSam Newmanによるマイクロサービスを取り上げた2冊目の書籍となります。

O'Reilly Japan - モノリスからマイクロサービスへ

本書は、モノリスからマイクロサービスアーキテクチャへと移行するための実践的なガイドです。マイクロサービスが自分たちのシステムに適しているかを判断するところから、ビジネスを維持しながらモノリシックなシステムを少しずつマイクロサービスに切り替えていく方法、さらには、マイクロサービスアーキテクチャが成長するにつれて起こる課題への対処の仕方まで、豊富な例やシナリオを用いて解説します。また、モノリスやデータベースを分解していくのに役立つ様々なパターンやテクニックも扱います。

身も蓋もないタイトルが示す通り、本書は「モノリスからマイクロサービスへ」の移行ガイドです。

移行の計画、マイクロサービスのモデリングの仕方、既存のアーキテクチャをマイクロサービスに移行する際に使える実績あるパターンやテクニックーーー本書は、モノリシックなシステムを持つ組織がマイクロサービスアーキテクチャを導入するにあたっての検討材料を幅広く提供する実用書となっています。

ですが、本書は「今すぐにモノリスを止めて、マイクロサービスへ行こう」と無邪気にマイクロサービスを啓蒙する書籍というわけではありません。現実に立脚し、いかにマイクロサービスアーキテクチャが難しく、困難を伴うかを教えてくれ、そして、不必要にマイクロサービスへと飛び込まないことを私たちに強く促します。

それでもマイクロサービスアーキテクチャが自分たちにとって良い選択肢だと思えるときーー本書は、そうした場合にどうやってそこに向かっていくかを、その困難さとともに教えてくれる一冊となっています。

目次

はじめに
1章 必要十分なマイクロサービス
1.1 マイクロサービスとは
1.1.1 独立デプロイ可能性
1.1.2 ビジネスドメインに基づくモデル化
1.1.3 自分たちのデータを所有する
1.1.4 マイクロサービスがもたらす利点
1.1.5 マイクロサービスが作り出す問題
1.1.6 ユーザーインターフェイス
1.1.7 技術
1.1.8 サイズ
1.1.9 所有権
1.2 モノリス
1.2.1 単一プロセスのモノリス
1.2.2 分散モノリス
1.2.3 サードパーティ製のブラックボックスシステム
1.2.4 モノリスの課題
1.2.5 モノリスの利点
1.3 結合と凝集
1.3.1 凝集
1.3.2 結合
1.4 必要十分なドメイン駆動設計
1.4.1 集約
1.4.2 境界づけられたコンテキスト
1.4.3 集約と境界づけられたコンテキストをマイクロサービスにマッピングする
1.4.4 参考文献
1.5 この章のまとめ
2章 移行を計画する
2.1 目的を理解する
2.1.1 3つの重要な質問
2.2 マイクロサービスを選択する理由
2.2.1 チームの自律性を高める
2.2.2 市場投入までの時間を減らす
2.2.3 負荷への費用対効果が高いスケーリング
2.2.4 堅牢性を改善する
2.2.5 開発者の数を増やす
2.2.6 新しい技術を受け入れる
2.3 マイクロサービスが悪いアイデアのとき
2.3.1 不明瞭なドメイン
2.3.2 スタートアップ
2.3.3 顧客の環境にインストールして管理するソフトウェア
2.3.4 もっともな理由を持たないとき
2.4 トレードオフ
2.5 みんなを連れていく
2.6 組織を変革する
2.6.1 危機意識を高める
2.6.2 変革推進のための連帯チームを築く
2.6.3 ビジョンと戦略を生み出す
2.6.4 変革のためのビジョンを周知徹底する
2.6.5 従業員の自発を促す
2.6.6 短期的成果を実現する
2.6.7 成果を活かして、さらなる変革を推進する
2.6.8 新しい方法を企業文化に定着させる
2.7 段階的に移行していくことの重要性
2.7.1 本番環境が重要
2.8 変更のコスト
2.8.1 可逆的な判断と不可逆的な判断
2.8.2 試しやすい場所
2.9 どこから始めればよいか?
2.10 ドメイン駆動設計
2.10.1 どこまでやればいいか?
2.10.2 イベントストーミング
2.10.3 ドメインモデルを使った優先順位付け
2.11 組み合わせモデル
2.12 チームを再編成する
2.12.1 構造を変える
2.12.2 どこにでもフィットするやり方はない
2.12.3 変化を起こす
2.12.4 スキルを変える
2.13 うまくいっているかどうかを分かるには?
2.13.1 定期的なチェックポイントを設ける
2.13.2 定量的な測定
2.13.3 定性的な測定
2.13.4 サンクコストの錯誤を回避する
2.13.5 新しいやり方への選択肢を開いておく
2.14 この章のまとめ
3章 モノリスを分割する
3.1 モノリスを変更すべきかどうか
3.1.1 切り貼りか再実装か?
3.1.2 モノリスをリファクタリングする
3.2 移行パターン
3.3 パターン:ストラングラーアプリケーション
3.3.1 使い方
3.3.2 使いどころ
3.3.3 例:HTTPリバースプロキシ
3.3.4 データ?
3.3.5 プロキシの選択肢
3.3.6 プロトコルを変える
3.3.7 例:FTP
3.3.8 例:メッセージ傍受
3.3.9 その他のプロトコル
3.3.10 ストラングラーパターンのその他の例
3.4 機能を移行しながら振る舞いを変える
3.5 パターン:UI合成
3.5.1 例:ページ合成
3.5.2 例:ウィジェット合成
3.5.3 例:マイクロフロントエンド
3.5.4 使いどころ
3.6 パターン:抽象化によるブランチ
3.6.1 使い方
3.6.2 フォールバック機構として
3.6.3 使いどころ
3.7 パターン:同時実行
3.7.1 例:クレジットデリバティブの価格比較
3.7.2 例:Homegate社のリスティング
3.7.3 検証テクニック
3.7.4 スパイを使う
3.7.5 GitHub Scientist
3.7.6 ダークローンチとカナリアリリース
3.7.7 使いどころ
3.8 パターン:デコレーティングコラボレーター
3.8.1 例:ポイントプログラム
3.8.2 使いどころ
3.9 パターン:変更データキャプチャ
3.9.1 例:ポイントカードの発行
3.9.2 変更データキャプチャを実装する
3.9.3 使いどころ
3.10 この章のまとめ
4章 データベースを分割する
4.1 パターン:共有データベース
4.1.1 対処パターン
4.1.2 使いどころ
4.2 しかし、できない!
4.3 パターン:データベースビュー
4.3.1 パブリックな契約としてのデータベース
4.3.2 提示用のビュー
4.3.3 制限事項
4.3.4 所有権
4.3.5 使いどころ
4.4 パターン:データベースをラップするサービス
4.4.1 使いどころ
4.5 パターン:サービスのインターフェイスとしてのデータベース
4.5.1 マッピングエンジンを実装する
4.5.2 ビューとの比較
4.5.3 使いどころ
4.6 所有権を移す
4.6.1 パターン:集約を公開するモノリス
4.6.2 パターン:データ所有権の変更
4.7 データ同期
4.8 パターン:アプリケーションでのデータ同期
4.8.1 ステップ 1:データを一括で同期する
4.8.2 ステップ 2:同期のために書き込み、古いスキーマから読み取る
4.8.3 ステップ 3:同期のために書き込み、新しいスキーマから読み取る
4.8.4 このパターンを使うとき
4.8.5 使いどころ
4.9 パターン:トレーサー書き込み
4.9.1 データ同期
4.9.2 事例:Squareの注文
4.9.3 使いどころ
4.10 データベースを分割する
4.10.1 物理的なデータベースの分離と論理的なデータベースの分離
4.11 データベースとコードのどちらを最初に分割するか
4.11.1 データベースを最初に分割する
4.11.2 コードを最初に分割する
4.11.3 データベースとコードを一緒に分割する
4.11.4 結局どちらを最初に分割すべきか?
4.12 スキーマ分割の例
4.13 パターン:テーブルの分割
4.13.1 使いどころ
4.14 パターン:外部キーのコードへの移動
4.14.1 結合の移動
4.14.2 データの一貫性
4.14.3 使いどころ
4.14.4 例:共有静的データ
4.15 トランザクション
4.15.1 ACIDトランザクション
4.15.2 ACIDだとしても原子性に欠ける?
4.15.3 2フェーズコミット
4.15.4 分散トランザクションにはノーと言う
4.16 サーガ
4.16.1 サーガの障害モード
4.16.2 サーガの実装
4.16.3 サーガ vs 分散トランザクション
4.17 この章のまとめ
5章 成長の痛み
5.1 サービスが増えれば痛みも増える
5.2 所有権のスケール
5.2.1 この問題はどのようにして現れるか?
5.2.2 この問題はいつ発生するか?
5.2.3 取り得る解決策
5.3 破壊的変更
5.3.1 この問題はどのようにして現れるか?
5.3.2 この問題はいつ発生するか?
5.3.3 取り得る解決策
5.4 レポーティング
5.4.1 この問題はどのようにして現れるか?
5.4.2 取り得る解決策
5.5 監視とトラブルシューティング
5.5.1 この問題はいつ発生するか?
5.5.2 こうした問題はどのように現れるか?
5.5.3 取り得る解決策
5.6 開発者体験
5.6.1 この問題はどのようにして現れるか?
5.6.2 この問題はいつ発生するか?
5.6.3 取り得る解決策
5.7 あまりにも多くのものを実行している
5.7.1 この問題はどのようにして現れるか?
5.7.2 この問題はいつ発生するか?
5.7.3 取り得る解決策
5.8 エンドツーエンドテスト
5.8.1 この問題はどのようにして現れるか?
5.8.2 この問題はいつ発生するか?
5.8.3 取り得る解決策
5.9 全体最適と局所最適
5.9.1 この問題はどのようにして現れるか?
5.9.2 この問題はいつ発生するか?
5.9.3 取り得る解決策
5.10 堅牢性と回復性
5.10.1 この問題はどのようにして現れるか?
5.10.2 この問題はいつ発生するか?
5.10.3 取り得る解決策
5.11 孤児サービス
5.11.1 この問題はどのようにして現れるか?
5.11.2 この問題はいつ発生するか?
5.11.3 取り得る解決策
5.12 この章のまとめ
6章 終わりに

目次からもわかる通り、もちろん本書にはマイクロサービスの専門家である著者ならではの実践的なヒントも大いに散りばめられています。

ドメイン駆動設計を利用したサービスのモデリング方法や、サーガを用いてサービス同士を協調させる方法、サービスの数が増えてくる中で起こってくるさまざまな課題の兆候と対処の仕方。

こうした、実践の中で培われた筆者の幅広い知見は、すでにマイクロサービスに取り組まれている方にも多いに参考になるはずです。

翻訳を進めていく中で、技術的な意思決定に対する著者の誠実な態度や姿勢に、私自身は何度も癒され(不思議な表現だとは思いますが、一技術者として癒される自分がいました)、襟を正されました。

そのような誠実な態度で書かれた、このマイクロサービスについての書籍が、ぜひマイクロサービスの導入に関心を持っている現場や実際にマイクロサービス化に取り組んでいる現場をはじめ、さまざまな現場のたくさんの方々に届くことを願っています。

モノリスからマイクロサービスへ ―モノリスを進化させる実践移行ガイド

モノリスからマイクロサービスへ ―モノリスを進化させる実践移行ガイド

  • 作者:Sam Newman
  • 発売日: 2020/12/26
  • メディア: 単行本(ソフトカバー)

マイクロサービスアーキテクチャ

マイクロサービスアーキテクチャ

  • 作者:Sam Newman
  • 発売日: 2016/02/26
  • メディア: 単行本(ソフトカバー)

スクラムフェス札幌2020で招待講演を行いました #scrumsapporo

2020年11月5日から7日に開催されたスクラムフェス札幌2020で、招待講演を勤めました。

スクラムフェス札幌2020

運営の根本さんから最初に招待講演の打診があったのは、2020年の1月のことでした。うれしくはあったものの、正直最初は乗り気ではありませんでした。スクラムの集まりで招待講演をする資格があるとは自分に思えなかったし、なによりアジャイル札幌として今も活動している人たちの前で、ぼくが何を話せるだろうと考えたからです。

ぼく自身は2017年でアジャイル札幌の運営からは身を引かせてもらっていたし、フォーカスすべきものを絞った結果、アジャイル札幌の集まりに積極的に関わるということもなくなってしまっていました。彼らは活動を続け、積極的に外に出ていき、新しい人たちを迎え、アジャイル札幌として活動しているというのに。そんなぼくが、どの面を下げてみんなに何を話すのか、みんなの方がよっぽどその資格があるのではないか、そんな想いがありました。

感情的な問題はおいておいたとしても、実際のところ、どういうメッセージを伝えるべきなのか、という問題もありました。ぼくが抱えているコンテキストと重なるような現場が、札幌にどれだけあるのか。スクラムの専門家でもないぼくに、スクラムの話はできない。

それでも、引き受けることにしました。なぜこのイベントをやるのか、なぜぼくなのか、根本さんにそう尋ねた答えから、これを引き受けることがぼくの仕事だと強く感じたからです。

発表の準備は、覚悟していたとはいえ、想像していたよりもずっと困難なものでした。それでも、結果としては、今のぼくからアジャイル札幌という場に返せる最善な講演ができたように思います。

でも、それができたのは、それがアジャイル札幌の場だったから、なんだろうと考えています。今のアジャイル札幌の人たちが、オンラインであってもあんな風な手触りのする、あたたかいイベントを準備し、作ってくれたおかげで、それを後押しにして、発表を「完成」できたのだと考えています。ありがとうございました。


今回の講演内容は、Notionでまず全体のスクリプトを書き、それをスライド単位に分解してスライドの内容を考え(2段組みにすっとできるNotionべんり)、さらにその状態で通して話してみてスクリプトとスライド内容を手直しするということを数イテレーション行った上で最後にKeynoteに起こす、という方法で準備を行いました。Keynoteに起こした後も最後まで手を加え続けていたので、スライドと多少違っている箇所もあるとは思いますが、スクリプトを残しておくことにも価値があるのではと思い、Notion上で準備を行なっていたページを(多少整理した上で)公開しておくことにします。

https://www.notion.so/Agile-Sapporo-Learn-from-experience-and-continue-to-repair-wholeness-9d6490014ca14eb0bb2d26a7060b3a0b

Connascence:コードの結合度を測るもうひとつの指標

構造は、凝集度が高く、結合度が低い場合に安定する - Larry Constantine

私たちプログラマーは、その仕事において、できる限り良いコードを書きたいと考えます。しかし、「良いコードとは何か」という問いに対して答えるのは、そう簡単ではありません。「良さ」を測るには、「何に対して」という軸が必要であり、その軸は一つではなく、さらには、コードを書いている状況に応じて、大事にすべき軸が変わるということも往々にしてあるからです。そうしたとき、私たちは何らかの尺度でもってコードを測って、そのときのコンテキストにおいて良い落とし所を定めます。

そのようなときに、コードの品質を測る軸としては、有名なものには「凝集性(Cohesion)」と「結合度(Coupling)」があります。ここでは、そのうちの「結合度」を測る指標の一つとして「コナーセンス(Connascence)」を紹介します。

コードの結合度を測る指標

コードの結合度を測る指標としては、『高信頼性ソフトウェア : 複合設計』や『ソフトウェアの複合/構造化設計』などでGlenford Myersによって提唱されたモジュール結合度が有名です。

https://ja.wikipedia.org/wiki/結合度

しかし、モジュール結合度は、現在のプログラミング言語ではすでに問題にしずらかったり、読み替えたりしないと理解が難しい尺度なども混ざっていたりして、今の私たちが尺度にするには少し難しくなってしまっています。

また、他に代表的な結合度の指標としては、『ソフトウェアの構造化設計法』においてEdward Yourdon と Larry Constantineが定義した「主系列からの距離(Distance from the main sequence)」があります。

ソフトウェアのメトリクスの基本的なところ

「主系列からの距離」は、コンポーネントの「不安定性」(「求心性結合(依存入力数、ファンイン)」と「遠心性結合(依存出力数、ファンアウト)」から求められる)と「抽象度」の理想的なバランスからの距離を求めるもので、それによってコンポーネントの依存度や抽象度が適切かが測れます。これは良い指標の一つではありますが、これはこれで、私たちがコードを見ただけで導き出すことは難しいため、コードを書いているときなどに意識する尺度としては少々扱いづらいところもあります。

これらと比べて、「コナーセンス(Connascence)」は、私たちプログラマーがコードを評価したり、リファクタリングする際に比較的意識しやすい尺度が定義されているものであり、その割に知名度が低いと感じるもののため、ここで紹介しようと考えました。

コナーセンス

コナーセンス(Connascence)とは、1992年にMeilir Page-Jones によって考案されたソフトウェア品質指標で、それまでの結合メトリクスを改良して、オブジェクト指向言語用に再構築したものとなります。

https://en.wikipedia.org/wiki/Connascence

コナーセンスという用語は

two components are connascent if a change in one would require the other to be modified in order to maintain the overall correctness of the system (システムの全体的な正しさを維持するために、一方の変更が他方の変更を必要とする場合、2つのコンポーネントはコナーセントである)

という文章からきており、コナーセント(connascent)とは「con- + nascent (「共に」「出現する」)という意味になります。

コナーセンスの特徴

コナーセンスでは、以下の3つの尺度(次元)を用いて、コードの品質を評価します。

https://programhappy.net/wp-content/uploads/2020/06/connascence-properties-diagram.png

引用: https://programhappy.net/2020/06/22/connascence-why-is-it-so-important/

度合い(Degree)

どれだけ結合されているか。結合の度合いが強い(高い)ほど、変更の難易度およびコストが高くなる

強度(Strength)

コナーセンスには種類(後述)に応じて強度があり、強いコナーセンスほど変更の難易度とコストが高くなる

距離(Locality)

関係する要素がどれだけ近いか。同じ強度と度合いのコナーセンスでも、関係する要素が離れているほど、変更の難易度とコストが高くなる

結合といって一般に想像される度合い(degree)に加えて、強度(strength)と距離(locality)という次元を持たせているところが、コナーセンスの大きな特徴となります。

コナーセンスを数値として計算する場合には、以下のような式で数値を検出します。

Strength x Degree / Locality

コナーセンスの種類

強度のところで触れたコナーセンスの種類には、次のようなものがあります。これらは、コンポーネントが何によって結びついているかに従った分類となっています。

  • 静的なコナーセンス: コードレベルで生じる結びつき
    • 名前のコナーセンス Connascence of Name (CoN)
      • 他方のコンポーネントが持つ要素の名前(メソッド名など)を参照している状態
    • 型のコナーセンス Connascence of Type (CoT)
    • 意味のコナーセンス Connascence of Meaning (CoM)
    • 位置のコナーセンス Connascence of Position (CoP)
      • メソッドのパラメータ順序などを知っている必要がある状態
    • アルゴリズムのコナーセンス Connascence of Algorithm (CoA)
  • 動的なコナーセンス: 実行時に生じる結びつき
    • 実行順序のコナーセンス Connascence of Execution (CoE)
      • 他方のコンポーネントを利用するにあたって、メソッドなどの実行順を知っている必要がある状態
    • タイミングのコナーセンス Connascence of Time (CoT)
      • 他方のコンポーネントを利用するにあたって、実行タイミングなどを知っている必要がある状態
    • 値のコナーセンス Connascence of Value (CoV)
      • コンポーネントが持つ値同士が関連していて、同期をとって管理する必要がある状態
    • アイデンティティのコナーセンス Connascence of Identity (CoI)

これらは、上のコナーセンスほど結びつきの強度が弱く、下にいくほど強度が強い、という関係になっており、できるだけ弱いコナーセンスに向けてリファクタリングするのが良いとされています。

https://res.cloudinary.com/practicaldev/image/fetch/s--i1piwW4k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/olhdijilxlv9b5txzkj6.png

参考 https://dev.to/edisonnpebojot/architecting-modules-for-software-modularity-part-2-3bpc

コナーセンスをどのように意識するか

ここからは、具体的なコードを見ながら、コードを書くときにどのようにコナーセンスを意識するかの例を見ていきましょう。

例1: 意味のコナーセンスを名前のコナーセンスに変換して、コナーセンス強度を下げる

たとえば、以下のようなコードがあったとします。

class Itemdef price(tax_included=false)
    if tax_included
       price * TAX
    else
       price
    end
  endend

この Item#price を利用するには、引数に渡す truefalse の意味を利用者側のコンポーネントが知っている必要があります。この状態は、意味のコナーセンスが生じている状態といえます。

これを、名前を知っていればメソッドを利用できる状態にしましょう。

class Itemdef price_including_tax
    price * TAX
  endend

これで、メソッド名さえ知っていればコンポーネントを利用できるようになりました。

例2: 実行順序のコナーセンス→位置のコナーセンス→名前のコナーセンス

たとえば、以下のようなコードがあったとします。

email = Mail.new
email.recipient "foo@example.com"
email.sender "me@example.com"
email.subject "Hi"
email.body "Hello"
email.send

このとき、たとえば Mail#recipientMail#subject といったメソッドは Mail#send の手前で呼び出す必要があるとします。この場合には、 Mail と利用者側のコンポーネントには実行順序のコナーセンスが生じている状態といえます。

これは、手続きが個々のメソッドに分かれていることが原因ですので、まずは手続きをひとまとめにしましょう。

class Mail
  ...
  def send(from, to, subject, body)
     ...
  end
end

これで、実行順序を気をつけなくてもメソッドを利用できるようにはなりました。

email.send("foo@example.com", "me@example.com", "Hi", "Hello")

しかし、今度は引数の順序を知らなければコンポーネントを正しく利用できません。この状態は、 Mailと利用者側のコンポーネントには位置のコナーセンスが生じている状態といえます。

次は、このメソッドにパラメータ引数を導入して、位置を知らなくてもメソッドを利用できるようにしましょう。

class Mail
  ...
  def send(from:, to:, subject:, body:)
    ...
  end
end

これで、位置を知らなくてもメソッドを利用できるようになりました。

email.send(
  from:    "foo@example.com",
  to:      "me@example.com",
  subject: "Hi",
  body:    "Hello"
)

この状態は、メソッド名とパラメータ名を知っていればメソッドを利用できるので、名前のコナーセンスがある状態といえます。

コナーセンスを設計のものさしに使う

どうだったでしょうか。もちろん、コナーセンスを知らなくても、自然と上記のような設計判断をするよという方もいるとは思います。ですが、コナーセンスの概念を用いることで、上記のような判断をある程度しっかりとした軸をもって進められそうな感じがしないでしょうか。少なくともモジュール結合度よりは今のコンテキストに素直にのせて評価しやすい指標ではないかなと考えます。

また、上記の例では、コナーセンスの種類(強度)だけにフォーカスしていましたが、ここに距離や度合いの観点も踏まえて考えると、さらにより良い判断のヒントが得られるだろうと考えています。

たとえば、位置のコナーセンスが生じていたとしても、2個の引数の場合と7個の引数の場合とでは、その度合いが異ります。あるいは、メソッドが同じファイル内からしか利用できない場合と、自分たちがメンテナンスしていないコードから利用される場合とでは、その距離が異なります。こうしたことを踏まえて、じゃあどのコナーセンスで十分としようか、といった具合です。

コナーセンスは他の尺度と比べるとだいぶマイナーなコンセプトで、日本語書籍で扱っているのも今のところは『Adaptive Code ~ C#実践開発手法 第2版』 (日経BP)くらい、英語圏でもそこまで流通はしていなさそうです。僕が調べた中では、RubyistにはおなじみのJim Weirichが2012〜2013年あたりに講演している内容がもっとも充実していると感じました。よければ時間のあるときにでも眺めてみてもらえたら嬉しいです。

www.youtube.com

以上で、簡単なコナーセンスの紹介を終わります。この記事が、より良い設計のヒントになれば幸いです。

参考文献

What Every Programmer Should Know About Object-Oriented Design

What Every Programmer Should Know About Object-Oriented Design

『レガシーコードからの脱却』を読んだ

本書はタイトルに「レガシーコード」と入っているため、イメージ的に『レガシーコード改善ガイド (Object Oriented SELECTION)』『レガシーソフトウェア改善ガイド (Object Oriented Selection)』といった書籍といった系譜の書籍を思い浮かべる人もいるかもしれない。しかし、実際には本書は『アジャイルソフトウェア開発の奥義 第2版 オブジェクト指向開発の神髄と匠の技』や『Clean Code アジャイルソフトウェア達人の技』、『アジャイルプラクティス 達人プログラマに学ぶ現場開発者の習慣』といった書籍の系譜、すなわち「より良いソフトウェアを作り出すために(レガシーコードを生み出さないために)どのようなテクニック、スキル、考え方が必要か」を説いている書籍だ。

本書は、大きくそれを次の9つのプラクティスにまとめ、1つずつをとても読みやすい内容、文量で教えてくれる。

  • やり方より先に目的、理由、誰のためかを伝える
  • 小さなバッチで作る
  • 継続的に統合する
  • 協力しあう
  • 「CLEAN」コードを作る
  • まずテストを書く
  • テストでふるまいを明示する
  • 設計は最後に行う
  • レガシーコードをリファクタリングする

本書を読んでとくにいいなあと思ったのは、ところどころで原則とプラクティスの関係、原則を見失わないように、というアドバイスを著者がはさんでくれることだ。

原則はドライブの目的地で、プラクティスはその道筋である。(...略...)プラクティスは私たちが原則を理解するのを助けてくれるし、原則は私たちがプラクティスを正しく使うのを助けてくれる。ただ、両方に目を配っておかなければ、迷子になってしまう。やり方をまったく知らない偉大な理論家か、日々のタスクはこなせても終わりを見通せない実務家のどちらかになってしまう。両方のバランスが必要だ。

こうした原則への目線は、XPに触れたときに感じた「間違えない方に方向付けしてくれる感じ」を思い出させてくれ、安心できる感じ、信頼できる感じを与えてくれる。

同じ系譜の書籍群は、いずれをとってもその厚さ(ぜんぶが500-600ページくらいの厚さ)と価格からなかなか多くの人に手に取ってもらうことは難しい。それに比べて、本書は前述の書籍群の内容をうまくカバーしながら、それを300ページという文量に抑えており、多くの人に手に取ってもらえる形にしていることがとても素晴らしいと感じた。技術的卓越に関するプラクティスが散りばめられているところも、本書を良いと思うことの一つだ。

これから現代的な技術プラクティスを身につけていこうとする人やチームに何か書籍を1つお勧めするなら、本書は最良の一冊だろう。

『Design It! ― プログラマーのためのアーキテクティング入門』

翻訳を担当した書籍『Design It! ― プログラマーのためのアーキテクティング入門』(オライリー・ジャパン)が11月25日に発売になります。本書は2017年にPragmatic Bookshelfより出版されたMichael Keeling著『Design It!: From Programmer to Software Architect』の全訳です。Pragmatic Bookshelfファンにはおなじみの「... It!」シリーズの一冊で、日本語で読める「... It!」シリーズとしては4冊目の書籍となります。

O'Reilly Japan - Design It!

本書は、設計スキルを成長させたいプログラマーに向けたアーキテクティングの入門書です。ソフトウェアアーキテクチャの基礎とデザイン思考の考え方から始まり、ソフトウェアアーキテクトとして、チームと共に優れたソフトウェアを作り上げていく方法を包括的に解説します。本書を読むことで、適切なステークホルダーを特定してニーズを理解する方法、アーキテクチャ上重要な要求に基づいて技術やアーキテクチャを適切に選択する方法、アーキテクチャを軽量かつ効果的に評価する方法、チームのアーキテクト力を高める方法などを学べます。モダンなアーキテクチャ設計のための実践的な手法が詰まった本書は、より良いプログラマー、技術リーダー、そしてソフトウェアアーキテクトになるために必携の一冊です。平鍋健児氏による「日本語版序文」を収録。

本書のテーマは、ソフトウェアをデザインすることです。主にアーキテクトの役割に焦点をあて、ソフトウェアの根幹となる部分、すなわち、ソフトウェアアーキテクチャをいかにデザインしていくかについての書籍となっています。そして、原書の「From Programmer To Software Architect(プログラマーからソフトウェアアーキテクトへの道)」というサブタイトルが示すように、今日のソフトウェア開発の現場で、新しい人たちがどうやってアーキテクト的な責任に踏み込んでいったらよいかというガイドにもなっています。

本書が良いなあと思うのは、とりあえずこれ一冊あれば、ビジネスを支えるソフトウェアのアーキテクティングにどう取り組んでいったらいいかの地図とコンパスを手に入れられるようになっているところです。

目次

第Ⅰ部 ソフトウェアアーキテクチャ入門

1章 ソフトウェアアーキテクトになる
    1.1 ソフトウェアアーキテクトが行うこと
    1.2 ソフトウェアアーキテクチャとは何か
    1.3 チームのアーキテクトになる
    1.4 素晴らしいソフトウェアを作り上げる
    1.5 ケーススタディ: Lionheartプロジェクト
    1.6 次にやること 

2章 デザイン思考の基礎
    2.1 デザイン思考の4つの原則
    2.2 デザインマインドセットを身に付ける
    2.3 Think、Do、Check
    2.4 次にやること

第Ⅱ部 アーキテクチャ設計の基礎

3章 デザイン戦略を立てる
    3.1 満足のいく設計を見つける
    3.2 どれくらい前払いの設計を行うかを決める
    3.3 リスクに道案内させる
    3.4 設計計画を立てる
    3.5 Lionheartプロジェクト:ここまでのあらすじ
    3.6 次にやること 

4章 ステークホルダーに共感する
    4.1 適切な人たちと話をする
    4.2 ステークホルダーマップを作る
    4.3 ビジネス目標を発見する
    4.4 Lionheartプロジェクト:ここまでのあらすじ
    4.5 次にやること 

5章 アーキテクチャ上重要な要求を掘り下げる
    5.1 制約によって設計の選択肢を絞る
    5.2 品質特性を定義する
    5.3 機能要求の分類を探す
    5.4 それ以外のアーキテクチャに影響するものを見つけ出す
    5.5 必要な情報を掘り下げる
    5.6 ASRワークブックを組み立てる
    5.7 Lionheartプロジェクト:ここまでのあらすじ
    5.8 次にやること

6章 アーキテクチャを選ぶ(君がアーキテクチャに選ばれる前に)
    6.1 選択肢を広げるために発散させ、決定するために収束させる
    6.3 制約を受け入れる
    6.2 望ましい品質特性を促進する
    6.4 機能的責務を要素に割り当てる
    6.5 変化に向けて設計する
    6.6 Lionheartプロジェクト:ここまでのあらすじ
    6.7 次にやること 

7章 パターンで土台を作る
    7.1 アーキテクチャパターンとは
    7.2 レイヤー(Layers)
    7.3 ポートとアダプター(Ports and Adapters)
    7.4 パイプとフィルター(Pipe and Filter)
    7.5 サービス指向アーキテクチャ(Service-Oriented Architecture)
    7.6 パブリッシュ・サブスクライブ(Publish-Subscribe)
    7.7 共有データ(Shared-Data)
    7.8 多層(Multi-Tier)
    7.9 コンピタンスセンター(Center of Competence)
    7.10 オープンソース型の貢献(Open Source Contribution)
    7.11 巨大な泥団子(Big Ball of Mud)
    7.12 新しいパターンを発見する
    7.13 Lionheartプロジェクト:ここまでのあらすじ
    7.14 次にやること 

8章 意味のあるモデルで複雑さを扱う
    8.1 アーキテクチャを見通す
    8.2 メタモデルを記述する
    8.3 コード内にモデルを構築する
    8.4 Lionheartプロジェクト:ここまでのあらすじ
    8.5 次にやること

9章 アーキテクチャデザインスタジオを開く
    9.1 アーキテクチャデザインスタジオを計画する
    9.2 適切なデザインアクティビティを選択する
    9.3 適切な参加者を招く
    9.4 グループを管理する
    9.5 リモートチームと実施する
    9.6 Lionheartプロジェクト:ここまでのあらすじ
    9.7 次にやること 

10章 設計判断を可視化する
    10.1 異なる視点からアーキテクチャを示す
    10.2 素晴らしい図を描く
    10.3 Lionheartプロジェクト:ここまでのあらすじ
    10.4 次にやること 

11章 アーキテクチャを記述する
    11.1 全体像を語る
    11.2 状況に応じた記述方法を選ぶ
    11.3 聴衆に配慮する
    11.4 ステークホルダーの関心事を中心にビューを構成する
    11.5 判断の論理的根拠を説明する
    11.6 Lionheartプロジェクト:ここまでのあらすじ
    11.7 次にやること 

12章 アーキテクチャに通知表をつける
    12.1 評価し、そこから学ぶ
    12.2 設計をテストする
    12.3 評価ワークショップを開く
    12.4 早くから評価を始め、頻繁に継続的に評価する
    12.5 Lionheartプロジェクト:ここまでのあらすじ
    12.6 次にやること 

13章 チームのアーキテクト力を強める
    13.1 アーキテクチャ思考を促進する
    13.2 意思決定を促し、スキルの成長を促進する
    13.3 安全に実践する機会を作り出す
    13.4 設計権限を委譲する
    13.5 共にアーキテクチャを設計する
    13.6 Lionheartプロジェクト:大団円
    13.7 次にやること 

第Ⅲ部 アーキテクトの道具箱

14章 問題理解のアクティビティ
    アクティビティ 1 たった一つを選ぶ 
    アクティビティ 2 共感マップ 
    アクティビティ 3 GQMワークショップ 
    アクティビティ 4 ステークホルダーインタビュー 
    アクティビティ 5 前提リスト 
    アクティビティ 6 品質特性ウェブ 
    アクティビティ 7 ミニ品質特性ワークショップ 
    アクティビティ 8 POV Madlib 
    アクティビティ 9 応答測定のたたき台 
    アクティビティ 10 ステークホルダーマップ

15章 潜在的な解決策を探るアクティビティ
    アクティビティ 11 アーキテクチャの擬人化
    アクティビティ 12 アーキテクチャフリップブック 
    アクティビティ 13 CRCカード
    アクティビティ 14 概念マップ 
    アクティビティ 15 分割統治 
    アクティビティ 16 イベントストーミング 
    アクティビティ 17 グループポスター 
    アクティビティ 18 ラウンドロビン設計 
    アクティビティ 19 ホワイトボードジャム 

16章 設計をタンジブルにするアクティビティ
    アクティビティ 20 アーキテクチャデシジョンレコード 
    アクティビティ 21 アーキテクチャ俳句 
    アクティビティ 22 コンテキスト図 
    アクティビティ 23 まずこれを読もうリスト
    アクティビティ 24 インセプションデッキ 
    アクティビティ 25 モジュール分解図 
    アクティビティ 26 選ばなかった道 
    アクティビティ 27 学習か判断のためのプロトタイプ 
    アクティビティ 28 シーケンス図
    アクティビティ 29 システムメタファー 

17章 設計の選択肢を評価するアクティビティ
    アクティビティ 30 アーキテクチャブリーフィング 
    アクティビティ 31 コードレビュー 
    アクティビティ 32 意思決定マトリクス 
    アクティビティ 33 振る舞いの観察 
    アクティビティ 34 質問-意見-懸念 
    アクティビティ 35 リスクストーミング 
    アクティビティ 36 サニティチェック 
    アクティビティ 37 シナリオウォークスルー
    アクティビティ 38 スケッチして比較

今日では、事業会社に所属し、そのビジネスを支えるソフトウェアの開発に携わるソフトウェア開発者も増えてきています。一方で、ソフトウェアをビジネスとうまく調和させた形で作り上げていく、ビジネス領域の人たちと一緒になってソフトウェアを育てていくという部分では課題がある組織もまだまだ多くあると感じています。そして、そうした課題に影響を与えているものの一つには、組織構造やこれまでのキャリアからくる無意識の線引きに影響され、私たちの側が旧来通りのソフトウェア開発のアプローチ(発注=仕様を決める側と受注=作る側)にとどまってしまっているケースも多くあると考えています。

本書は、プログラマーがそうした壁を破って、ビジネスと調和したソフトウェアをチームでデザインしていくためのヒントが得られる一冊です。

訳者後書きにも書いたことなのですが、この「... It!」シリーズというのは、自分にとって思い入れのあるシリーズで、10年ほど前の自分にとって『Ship It!』をはじめとするこのシリーズの書籍たちを「今世界のどこかで、こうやったやり方や考え方で開発していっている人たちが実際にいる!」という感覚を持ちながら日本語で読めたことは、プログラマーとしての世界観を形成していくにあたって大事な経験でした。今回のぼくの仕事が、これまでの書籍を翻訳してこられた方々のように十分にうまくできたかはわかりませんが、願わくば、当時のぼくと同じような気持ちで本書から何かを受け取ってくれる人に、この本が届くといいなと思っています。

本書の出だしは、次のような一行からはじまります。

ソフトウェアアーキテクチャとは、素晴らしいソフトウェアを構築するための土台だ。もちろん、アーキテクチャが素晴らしいからといって、ソフトウェアの成功が保証されるわけではない。しかし、多くの場合、誤ったアーキテクチャは失敗につながる。ソフトウェアアーキテクチャはとても重要なものだ。だからこそ、すべてのソフトウェア開発者はそれをどう設計するかを知る必要がある。

ぜひ、たくさんの方に読んでいただけると嬉しいです。

Design It! ―プログラマーのためのアーキテクティング入門

Design It! ―プログラマーのためのアーキテクティング入門

『進化的アーキテクチャ ― 絶え間ない変化を支える』

翻訳を担当した書籍『進化的アーキテクチャ ― 絶え間ない変化を支える』(オライリー・ジャパン)が8月18日に出版になります。原書は2017年に出版された『Building Evolutionary Architectures ― Support Constant Change』(O'Reilly Media)です。

O'Reilly Japan - 進化的アーキテクチャ

現代におけるエンタープライズアーキテクチャは、もはや静的な計画をあてにすることはできなくなっています。そしてソフトウェア開発エコシステムは、ツールやフレームワーク、技術イノベーションの流れと共に絶え間なく変化しています。こうした状況の中で、いったん構築したシステムを成長させていくには、さまざまな変化に適応しながら進化するアーキテクチャをシステムに組み込む必要があります。本書は、そうしたアーキテクチャを「進化的アーキテクチャ」と名付け、その構築に必要な考え方や技術、実践方法などについて解説するものです。 ThoughtWorksの3人のスペシャリストから現代のソフトウェアアーキテクトに向けられた本書は、絶え間ない変化を支える進化的アーキテクチャを構築するために必要なすべてを提供する実践的なガイドです。

進化的アーキテクチャ(Evolutionary Architechture)」という考え方や重要性については、これまでにも何度かThoughtWorks関係者から語られてきていました。

例えば、Sam Newman『マイクロサービスアーキテクチャ』の結びは、

進化的アーキテクチャの概念を採用する方法を身に付けましょう。進化的アーキテクチャでは、あなたが新しいことを学ぶにつれシステムは徐々に柔軟になり変化します。ビッグバン型の書き直しではなく、システムを徐々に変更していって柔軟性を保つようにしてください。

となっており、同書の内容が「進化的アーキテクチャ」という考えの傘の下にあることが伺えます。

また、Kief Morris『Infrastructure as Code ― クラウドにおけるサーバ管理の原則とプラクティス』でも、「15章 Infrastructure as Codeのための組織」に「15.1 発展的なアーキテクチャ」(原書では「15.1 Evolutionary Architecture」)という節が設けられており、こちらでもやはり進化的アーキテクチャという考えが前提にあることが確認できます。

そして、元ThoughtWorkerのJez Humbleが共著を務める『The DevOps ハンドブック 理論・原則・実践のすべて』でも「進化的アーキテクチャ」はちょこちょこと顔を出し、

これは発展的なアーキテクチャの原則である。Jez Humbleは、「成功を収めた製品、組織のアーキテクチャは、かならずライフサイクルの過程で必要に迫られて発展します」と語っている。

発展的なアーキテクチャをサポートすれば、アーキテクチャは組織のそのときどきのニーズを満たすものになる。

といった具合に、ThoughtWorkerたちに「進化的アーキテクチャ」という考え方が根付いていることが確認できます(いずれも「第13章 ローリスクリリースのアーキテクチャ」より引用。こちらも訳語は「発展的なアーキテクチャ」となっていますが、原書では「Evolutionary Architecture」)。

しかしながら、これだけさまざまな文献から言及されつつも、ThoughtWorkerたちの考える「進化的アーキテクチャ」が一体どういったもので、それを実現するためにどうしたらいいのかをまとまって確認できる文献は存在していない状況でした。

本書は、ThoughtWorkerたちが「進化的アーキテクチャ」自体をテーマにして書いた初の書籍です。

本書の執筆陣は、ThoughtWorksのディレクターであるNeal Ford、CTOであるRebecca Parsons、主任コンサルタントであるPatrick Kua。序文はMartin Fowlerが務め、データベースを扱った第5章は『データベース・リファクタリング』の共著者としても知られるPramod Sadalageによる寄稿と、そうそうたる面子による書籍となっています。

ThoughtWorkerたちは、本書の刊行を皮切りに、進化的アーキテクチャのセッションを各地で精力的に行なっているようで、そのコンセプトはさまざまなフィードバックを受けてさらなる進化をしていくことは想像に難くありませんが(なにせ「進化的」を推進する側の彼らですから)、現代のソフトウェア開発におけるアーキテクチャの捉え方として興味深い内容が含まれている一冊になっていますので、ぜひ手に取っていただけると嬉しいです。

進化的アーキテクチャ ―絶え間ない変化を支える

進化的アーキテクチャ ―絶え間ない変化を支える

コミットメント言語で大事なのはそれが制御下にあるかどうか

拙訳『エラスティックリーダーシップ ―自己組織化チームの育て方』にコミットメント言語 (Commitment Language) というものがでてきます。コミットメント言語とは、簡単にいうと「言質を与える言い方」のことで、本書では「仕事では自分が何を行うかを言質を与える言い方で約束すべきである」という話で、このコミットメント言語というものがでてきます。

具体的にいうと、希望的な物言い(「したいと思います」「しようと思ってます」「やれると思います」)やコミットメントを表明しない言い方(「はやったほうがいいとは思っています」「やらないといけないとは思ってます」)をせず、やることを約束する言葉遣い(「〜します」)をするようにしましょうという話です。

ですが、実はここだけを切り取って読んでしまうと勿体なくて、著者のロイがコミットメント言語の章で伝えたい主旨は、単に言い方だけを変えなさいという話ではありません。本当に大事なのは、そのあとに著者が続けている「自分の制御下にあるものが何かを考えること」にあります。つまり、言質を与える言い方を選ぶことを通して、それぞれのメンバーが「自分が本当に約束できることは何か」を考え、そこから外れた指示、依頼を受けた場合には、自分でスコープを調整したりした上で、約束できることだけを約束できるようになっていかないといけないよね、という話がコミットメント言語の肝になります。

ともすると、「約束させられるための言葉遣い」のように受け取られかねないのですが、そんな風に流通してしまうと切ないなあと思って、僕が訳しながら受け取めていたことを少しだけ書いてみました。

ちなみに、コミットメント言語は「約束の言語 (Language of Commitment) 」としてロイが『Clean Coder プロフェッショナルプログラマへの道』に寄稿した内容が元になっています。ボブおじさんの書籍にロイが寄稿するという、ちょうど『エラスティックリーダーシップ』の逆の形ですね。もし両方の書籍を持っている人がいたら、読み比べてみると面白いかもしれません*1

エラスティックリーダーシップ ―自己組織化チームの育て方

エラスティックリーダーシップ ―自己組織化チームの育て方

Clean Coder プロフェッショナルプログラマへの道

Clean Coder プロフェッショナルプログラマへの道

*1:英語であれば http://www.informit.com/articles/article.aspx?p=1715058 から読めます