『ソフトウェアアーキテクチャ・ハードパーツーー分散アーキテクチャのためのトレードオフ分析』

翻訳を担当した書籍『ソフトウェアアーキテクチャ・ハードパーツ ―分散アーキテクチャのためのトレードオフ分析』(オライリー・ジャパン)が本日(10月27日)発売となります(電子書籍オライリー・ジャパンサイトから購入できます)。本書は、2021年10月に出版されたNeal Ford, Mark Richards, Pramod Sadalage, Zhamak Dehghani 著『Software Architecture: The Hard Parts』(O'Reilly Media)を全訳したものです。

本書は、『ソフトウェアアーキテクチャの基礎 ―エンジニアリングに基づく体系的アプローチ』(オライリージャパン)に続く、Neal FordとMark Richardsのタッグによるソフトウェアアーキテクチャを扱った書籍になります。前作には盛り込みきれなかった、現代の分散アーキテクチャでの意思決定が持つさまざまなトレードオフについて、その見極め方や評価の仕方、効果的な意思決定を行っていく方法を解説しています。

本書では、アーキテクチャ上の決定に与える影響としてデータに関するトピックにも深く踏み込んでおり、その領域に造詣の深いPramod SadalageとZhamak Dehghaniの二人が新たに共著者として加わっています1

耳なじみのない「ハードパーツ」という言葉を冠した本書のタイトルは、オライリーの「The Good Parts」シリーズのオマージュから2。ソフトウェアアーキテクチャという「ソフトウェアの中のハード(硬い)な部分」であり「べストプラクティスの存在しない領域」(ゆえに「Good Parts」とは言えない)、そしてそうしたソフトウェアアーキテクチャの「ハードパーツ(難しい問題)」を扱った書籍であることを意味しています。

同月に『マイクロフロントエンド ―マイクロサービスアーキテクチャの概念をフロントエンドに拡張し、信頼性、自律性の高いシステムを構築する』(序文は本書の著者の一人Neal Ford!)も刊行され、12月にはSam Numanの『マイクロサービスアーキテクチャ 第2版』の刊行も予定されていて、ソフトウェアアーキテクチャ周辺の注目書籍が盛りだくさんですが、ソフトウェアアーキテクチャに取り組むたくさんの方に手に取っていただけると嬉しいです。

目次

本書への推薦の言葉
はじめに

1章 「ベストプラクティス」がないとどうなる?
    1.1 なぜ「ハードパーツ」か?
    1.2 ソフトウェアアーキテクチャについての時代を超えたアドバイス
    1.3 アーキテクチャにおけるデータの重要性
    1.4 アーキテクチャデシジョンレコード
    1.5 アーキテクチャ適応度関数
        1.5.1 適応度関数の使用
    1.6 アーキテクチャと設計:定義をシンプルにする
    1.7 Sysops Squadサーガの紹介
        1.7.1 非チケッティングワークフロー
        1.7.2 チケッティングワークフロー
        1.7.3 悪いシナリオ
        1.7.4 Sysops Squadのアーキテクチャコンポーネント
        1.7.5 Sysops Squadデータモデル

第I部 分解する

2章 ソフトウェアアーキテクチャにおける結合の見分け方
    2.1 アーキテクチャ量子
        2.1.1 独立してデプロイ可能
        2.1.2 高度な機能的凝集
        2.1.3 高度な静的結合
        2.1.4 動的な量子結合
    2.2 Sysops Squadサーガ:量子を理解する

3章 アーキテクチャのモジュール化
    3.1 モジュール化の推進要因
        3.1.1 保守性
        3.1.2 テスト性
        3.1.3 デプロイ性
        3.1.4 スケーラビリティ
        3.1.5 可用性・耐障害性
    3.2 Sysops Squadサーガ:提案書の作成

4章 アーキテクチャの分解
    4.1 コードベースは分解可能か?
        4.1.1 求心性結合と遠心性結合
        4.1.2 抽象度と不安定度
        4.1.3 主系列からの距離
    4.2 コンポーネントベース分解
    4.3 戦術的フォーク
        4.3.1 トレードオフ
    4.4 Sysops Squadサーガ:分解アプローチを選択する

5章 コンポーネントベース分解パターン
    5.1 コンポーネントの特定およびサイズ調整パターン
        5.1.1 パターンの説明
        5.1.2 統制のための適応度関数
        5.1.3 Sysops Squadサーガ:コンポーネントのサイズ調整
    5.2 ドメイン共通コンポーネントの収集パターン
        5.2.1 パターンの説明
        5.2.2 統制のための適応度関数
        5.2.3 Sysops Squadサーガ:ドメイン共通コンポーネントの収集
    5.3 コンポーネントのフラット化パターン
        5.3.1 パターンの説明
        5.3.2 統制のための適応度関数
        5.3.3 Sysops Squadサーガ:コンポーネントのフラット化
    5.4 コンポーネントの依存関係判断パターン
        5.4.1 パターンの説明
        5.4.2 統制のための適応度関数
        5.4.3 Sysops Squadサーガ:コンポーネントの依存関係を特定する
    5.5 コンポーネントドメインの作成パターン
        5.5.1 パターンの説明
        5.5.2 統制のための適応度関数
        5.5.3 Sysops Squadサーガ:コンポーネントドメインの作成
    5.6 ドメインサービスの作成パターン
        5.6.1 パターンの説明
        5.6.2 統制のための適応度関数
        5.6.3 Sysops Squadサーガ:ドメインサービスの作成
    5.7 まとめ

6章 業務データの分解
    6.1 データ分解の推進要因
        6.1.1 データ分解要因
        6.1.2 データ統合要因
        6.1.3 Sysops Squadサーガ:データベース分解の根拠
    6.2 モノリシックなデータを分解する
        6.2.1 ステップ1:データベースを分析し、データドメインを特定する
        6.2.2 ステップ2:テーブルをデータドメインに割り当てる
        6.2.3 ステップ3:データベースコネクションをデータドメインごとに分離する
        6.2.4 ステップ4:スキーマを別個のデータベースサーバーに移動する
        6.2.5 ステップ5:個別のデータベースサーバーへコネクション先を切り替える
    6.3 データベース種別を選択する
        6.3.1 リレーショナルデータベース
        6.3.2 キーバリューデータベース
        6.3.3 ドキュメントデータベース
        6.3.4 列指向データベース
        6.3.5 グラフデータベース
        6.3.6 NewSQLデータベース
        6.3.7 クラウドネイティブデータベース
        6.3.8 時系列データベース
    6.4 Sysops Squadサーガ:ポリグロットデータベース

7章 サービスの粒度
    7.1 粒度分解要因
        7.1.1 サービスの範囲と機能
        7.1.2 コード変動率
        7.1.3 スケーラビリティとスループット
        7.1.4 耐障害性
        7.1.5 セキュリティ
        7.1.6 拡張性
    7.2 粒度統合要因
        7.2.1 データベーストランザクション
        7.2.2 ワークフローとコレオグラフィ
        7.2.3 共有コード
        7.2.4 データ関係
    7.3 適切なバランスを見極める
    7.4 Sysops Squadサーガ:チケット割り当ての粒度
    7.5 Sysops Squadサーガ:顧客登録の粒度

第II部 つなぎ合わせる

8章 再利用パターン
    8.1 コードレプリケーション
        8.1.1 使いどころ
    8.2 共有ライブラリ
        8.2.1 依存関係の管理と変更の制御
        8.2.2 バージョニング戦略
        8.2.3 使いどころ
    8.3 共有サービス
        8.3.1 変更リスク
        8.3.2 パフォーマンス
        8.3.3 スケーラビリティ
        8.3.4 耐障害性
        8.3.5 使いどころ
    8.4 サイドカーとサービスメッシュ
        8.4.1 使いどころ
    8.5 Sysops Squadサーガ:共通基盤ロジック
    8.6 コードの再利用:どのようなときに価値が生まれるか?
        8.6.1 プラットフォームによる再利用
    8.7 Sysops Squadサーガ:共有ドメイン機能

9章 データの所有権と分散トランザクション
    9.1 データの所有権を割り当てる
    9.2 単独所有シナリオ
    9.3 全体共有シナリオ
    9.4 共同所有シナリオ
        9.4.1 テーブルの分割
        9.4.2 データドメイン
        9.4.3 委譲
    9.5 サービスコンソリデーション
    9.6 データ所有権のまとめ
    9.7 分散トランザクション
    9.8 結果整合性パターン
        9.8.1 バックグラウンド同期パターン
        9.8.2 リクエストベースのオーケストレーションパターン
        9.8.3 イベントベースパターン
    9.9 Sysops Squadサーガ:チケット処理のデータ所有権

10章 分散データアクセス
    10.1 サービス間通信パターン
    10.2 列スキーマレプリケーションパターン
    10.3 レプリケーションキャッシュパターン
    10.4 データドメインパターン
    10.5 Sysops Squadサーガ:チケット割り当てのためのデータアクセス

11章 分散ワークフローの管理
    11.1 オーケストレーション通信スタイル
    11.2 コレオグラフィ通信スタイル
        11.2.1 ワークフロー状態管理
    11.3 オーケストレーションとコレオグラフィのトレードオフ
        11.3.1 状態の所有者と結合
    11.4 Sysops Squadサーガ:ワークフローを管理する

12章 トランザクショナルサーガ
    12.1 トランザクショナルサーガパターン
        12.1.1 エピックサーガ(sao)パターン
        12.1.2 伝言ゲームサーガ(sac)パターン
        12.1.3 おとぎ話サーガ(seo)パターン
        12.1.4 タイムトラベルサーガ(sec)パターン
        12.1.5 ファンタジーサーガ(aao)パターン
        12.1.6 ホラーストーリーサーガ(aac)パターン
        12.1.7 パラレルサーガ(aeo)パターン
        12.1.8 アンソロジーサーガ(aec)パターン
    12.2 結果整合性を備えた状態管理
        12.2.1 サーガ状態マシン
    12.3 サーガの管理手法
    12.4 Sysops Squadサーガ:アトミックトランザクションと補償トランザクション

13章 コントラクト
    13.1 厳格なコントラクトと緩いコントラクト
        13.1.1 厳格なコントラクトと緩いコントラクトのトレードオフ
        13.1.2 マイクロサービスにおけるコントラクト
    13.2 スタンプ結合
        13.2.1 スタンプ結合による過結合
        13.2.2 帯域幅
        13.2.3 ワークフロー管理におけるスタンプ結合
    13.3 Sysops Squadサーガ:チケットのコントラクトを管理する

14章 分析データの管理
    14.1 従来のアプローチ
        14.1.1 データウェアハウス
        14.1.2 データレイク
    14.2 データメッシュ
        14.2.1 データメッシュの定義
        14.2.2 データプロダクト量子
        14.2.3 データメッシュ、結合、アーキテクチャ量子
        14.2.4 データメッシュの使いどころ
    14.3 Sysops Squadサーガ:データメッシュ

15章 独自のトレードオフ分析を構築する
    15.1 絡み合う次元の発見
        15.1.1 結合
        15.1.2 結合点の分析
        15.1.3 トレードオフの評価
    15.2 トレードオフ手法
        15.2.1 定性的分析と定量的分析
        15.2.2 MECEリスト
        15.2.3 「コンテキスト外」の罠
        15.2.4 関連するドメインのシナリオをモデル化する
        15.2.5 根拠は示し過ぎず、肝心なものに絞る
        15.2.6 過度な売り込みやエバンジェリズムを避ける
    15.3 Sysops Squadサーガ:エピローグ

付録A 概念や用語の参照
付録B アーキテクチャデシジョンレコードの参照
付録C トレードオフの参照


  1. Pramod Sadalageは『データベース・リファクタリング 』の共著者。Zhamak Dehghaniは注目を集めているデータアーキテクチャのアプローチであるデータメッシュの提唱者。

  2. 日本語で読めるものとしては『JavaScript: The Good Parts』や『Web API: The Good Parts』などがあります。

『ソフトウェアアーキテクチャの基礎――エンジニアリングに基づく体系的アプローチ』

翻訳を担当した書籍『ソフトウェアアーキテクチャの基礎――エンジニアリングに基づく体系的アプローチ』(オライリー・ジャパン)が3月8日に発売されます。本書は、2020年1月に出版されたMark Richards, Neal Ford著『Fundamentals of Software Architecture』(O'Reilly Media)を全訳したものです。

www.oreilly.co.jp

ソフトウェアアーキテクチャとは、ソフトウェアシステムの成功に欠かせない重要な土台です。そのためソフトウェア開発者には、効果的なアーキテクチャを実現するスキルが求められます。本書は、そうした効果的なアーキテクチャを設計、構築、維持するアーキテクトになるために必要なスキルや知識を、現代的な視点から整理して包括的に解説する書籍です。 ソフトウェアアーキテクチャの定義から、アーキテクトの役割、モジュールや結合、アーキテクチャスタイルといったアーキテクチャ設計の基礎、チームやステークホルダーと効果的にコラボレーションしていくために必要なソフトスキルまで、さまざまなトピックについて実践的な例とともに説明します。

本書は、ソフトウェアアーキテクチャという分野が持つ多様な側面を現代的な視点から整理し、その基礎を詳述した書籍です。

今の時代を反映したソフトウェアアーキテクチャの書籍として

なぜ、ソフトウェアアーキテクチャの書籍を今新たに書く必要があったかについて、著者らは本書に関するインタビュー1で、今の時代を反映したソフトウェアアーキテクチャの書籍を書きたかったと、その動機を語っています。

たとえば、ソフトウェアアーキテクチャをデザインするときの重要な要素の一つに、アーキテクチャ特性 があります。アーキテクチャ特性とは、品質特性やイリティ(-ility)などとも呼ばれる、可用性(availability)や信頼性(reliability)、弾力性(elasticity)といった、システムがサポートしなければならない性質を指します。

ソフトウェアアーキテクチャを扱った多くの書籍では、システムレベルでこのアーキテクチャ特性を考えるのが、暗黙的な前提となっています。

しかし、マイクロサービスアーキテクチャ登場以降、アーキテクチャ特性はシステムレベルで考えるものではもはやなくなっていると著者らは主張します。そうでなく、共通のアーキテクチャ特性を備えなければならない範囲・境界をアーキテクチャ要素(たとえばマイクロサービスにおけるサービス)として設計していくことこそが、現代のソフトウェアアーキテクチャで重要なプロセスなのだと、著者らは語ります。

本書は、こうした、ソフトウェアアーキテクチャの分野で暗黙的に前提となっていた事柄を現代的な視点で見直し、今の時代に沿った形でソフトウェアアーキテクチャという分野を改めて包括的にまとめた書籍となっています。

開発者がアーキテクトとなるためのガイドとして

また、開発者がアーキテクトとなるための丁度良いガイドが存在していなかったことも、本書を執筆した動機であったと著者らは語っています。

このことが大きく反映されているのが、「1章 イントロダクション」「2章 アーキテクチャ思考」、そして第3部の「テクニックとソフトスキル」でしょう。これらの章では、ソフトウェアアーキテクトはどのような期待を満たすロールであるか、そのためにどのような考え方をしていく必要があるか(開発者というロールから、どのように考え方を変える必要があるか)、有効なアーキテクトであり続けるためにどのようにチームやステークホルダーとコラボレーションしていく必要があるかといった、アーキテクトというロール、キャリアを開いていくにあたっての実践的なヒントが詰め込まれています。

全体を通してメッセージとして語られる、「選択によるトレードオフを分析し、最善ではないかもしれないが少なくとも最悪ではないソリューションを選んでいく」ことも、これからのアーキテクトに向けた重要なアドバイスだと感じます。

新しい技術やプラットフォーム、製品を広めたい人たちによる「正解」が、世の中にはどうしても溢れています。ですが、現実世界のアーキテクトの仕事に「正解」はありません。少しずつ変化していく現実の状況に応じて、イテレーティブにアーキテクチャレベルの改善を重ねていくことが重要です。

訳者として、本書がそうしたアーキテクチャ感が広まる一助になればと良いなと考えます。400ページ弱とボリュームのある一冊となりますが、ぜひ手に取っていただけると幸いです。

目次

本書への推薦の言葉
はじめに:公理を疑う

1章 イントロダクション
    1.1 ソフトウェアアーキテクチャの定義
    1.2 アーキテクトへの期待
        1.2.1 アーキテクチャ決定を下す
        1.2.2 アーキテクチャを継続的に分析する
        1.2.3 最新のトレンドを把握し続ける
        1.2.4 決定の順守を徹底する
        1.2.5 さまざまなものに触れ、経験している
        1.2.6 事業ドメインの知識を持っている
        1.2.7 対人スキルを持ち合わせている
        1.2.8 政治を理解し、かじ取りをする
    1.3 アーキテクチャと交わるもの
        1.3.1 エンジニアリングプラクティス
        1.3.2 運用とDevOps
        1.3.3 プロセス
        1.3.4 データ
    1.4 ソフトウェアアーキテクチャの法則

第I部 基礎

2章 アーキテクチャ思考
    2.1 アーキテクチャと設計
    2.2 技術的な幅
    2.3 トレードオフを分析する
    2.4 ビジネスドライバーを理解する
    2.5 アーキテクティングとコーディングのバランスを取る

3章 モジュール性
    3.1 定義
    3.2 モジュール性の計測
        3.2.1 凝集度
        3.2.2 結合度
        3.2.3 抽象度、不安定度、主系列からの距離
        3.2.4 主系列からの距離
        3.2.5 コナーセンス
        3.2.6 結合度とコナーセンスのメトリクスを統合する
    3.3 モジュールからコンポーネントへ

4章 アーキテクチャ特性
    4.1 アーキテクチャ特性の(部分的な)リスト
        4.1.1 アーキテクチャの運用特性
        4.1.2 アーキテクチャの構造特性
        4.1.3 アーキテクチャの横断的特性
    4.2 トレードオフと少なくとも最悪でないアーキテクチャ

5章 アーキテクチャ特性を明らかにする
    5.1 アーキテクチャ特性をドメインの関心事から捉える
    5.2 要件からアーキテクチャ特性を抽出する
    5.3 事例:シリコンサンドイッチ
        5.3.1 明示的な特性
        5.3.2 暗黙的な特性

6章 アーキテクチャ特性の計測と統制
    6.1 アーキテクチャ特性の計測
        6.1.1 運用面の計測
        6.1.2 構造面の計測
        6.1.3 プロセス面の計測
    6.2 統制と適応度関数
        6.2.1 アーキテクチャ特性の統制
        6.2.2 適応度関数

7章 アーキテクチャ特性のスコープ
    7.1 結合とコナーセンス
    7.2 アーキテクチャ量子と粒度
        7.2.1 事例:Going、Going、Gone

8章 コンポーネントベース思考
    8.1 コンポーネントの分類
    8.2 アーキテクトの役割
        8.2.1 アーキテクチャの分割
        8.2.2 事例:シリコンサンドイッチにおける分割
    8.3 開発者の役割
    8.4 コンポーネントを識別する流れ
        8.4.1 初期コンポーネントを識別する
        8.4.2 コンポーネントに要件を割り当てる
        8.4.3 ロールや責務を分析する
        8.4.4 アーキテクチャ特性を分析する
        8.4.5 コンポーネントを再構成する
    8.5 コンポーネントの粒度
    8.6 コンポーネント設計
        8.6.1 コンポーネントの発見
    8.7 事例:「Going、Going、Gone」におけるコンポーネントの発見
    8.8 アーキテクチャ量子再び:モノリシックアーキテクチャと分散アーキテクチャの選択

第II部 アーキテクチャスタイル

9章 基礎
    9.1 基礎的なパターン
        9.1.1 巨大な泥団子
        9.1.2 ユニタリーアーキテクチャ
        9.1.3 クライアント/サーバー
    9.2 モノリシックアーキテクチャと分散アーキテクチャ
        9.2.1 誤信1:ネットワークは信頼できる
        9.2.2 誤信2:レイテンシーがゼロ
        9.2.3 誤信3:帯域幅は無限
        9.2.4 誤信4:ネットワークは安全
        9.2.5 誤信5:トポロジーは決して変化しない
        9.2.6 誤信6:管理者は一人だけ
        9.2.7 誤信7:転送コストはゼロ
        9.2.8 誤信8:ネットワークは均一
        9.2.9 分散コンピューティングにおけるその他の考慮事項

10章 レイヤードアーキテクチャ
    10.1 トポロジー
    10.2 層の分離
    10.3 レイヤーの追加
    10.4 その他の考慮事項
    10.5 このアーキテクチャスタイルを採用する理由
    10.6 アーキテクチャ特性の評価

11章 パイプラインアーキテクチャ
    11.1 トポロジー
        11.1.1 パイプ
        11.1.2 フィルター
    11.2 事例
    11.3 アーキテクチャ特性の評価

12章 マイクロカーネルアーキテクチャ
    12.1 トポロジー
        12.1.1 コアシステム
        12.1.2 プラグインコンポーネント
    12.2 レジストリ
    12.3 コントラクト
    12.4 事例とユースケース
    12.5 アーキテクチャ特性の評価

13章 サービスベースアーキテクチャ
    13.1 トポロジー
    13.2 トポロジーの種類
    13.3 サービスの設計と粒度
    13.4 データベース分割
    13.5 アーキテクチャ例
    13.6 アーキテクチャ特性の評価
    13.7 このアーキテクチャスタイルがふさわしいとき

14章 イベント駆動アーキテクチャ
    14.1 トポロジー
    14.2 ブローカー
    14.3 メディエーター
    14.4 非同期の能力
    14.5 エラー処理
    14.6 データロスの防止
    14.7 ブロードキャスト能力
    14.8 リクエスト・リプライ
    14.9 リクエストベースとイベントベースの間を取る
    14.10 ハイブリッドなイベント駆動アーキテクチャ
    14.11 アーキテクチャ特性の評価

15章 スペースベースアーキテクチャ
    15.1 一般的なトポロジー
        15.1.1 処理ユニット
        15.1.2 仮想ミドルウェア
        15.1.3 データポンプ
        15.1.4 データライター
        15.1.5 データリーダー
    15.2 データ衝突
    15.3 クラウドとオンプレミス
    15.4 レプリケーションキャッシュと分散キャッシュ
    15.5 ニアキャッシュの考慮
    15.6 実装例
        15.6.1 コンサートチケット販売システム
        15.6.2 オンラインオークションシステム
    15.7 アーキテクチャ特性の評価

16章 オーケストレーション駆動サービス指向アーキテクチャ
    16.1 歴史と哲学
    16.2 トポロジー
    16.3 分類
        16.3.1 ビジネスサービス
        16.3.2 エンタープライズサービス
        16.3.3 アプリケーションサービス
        16.3.4 インフラストラクチャサービス
        16.3.5 オーケストレーションエンジン
        16.3.6 メッセージフロー
    16.4 再利用...と結合
    16.5 アーキテクチャ特性の評価

17章 マイクロサービスアーキテクチャ
    17.1 歴史
    17.2 トポロジー
    17.3 分散
    17.4 境界づけられたコンテキスト
        17.4.1 粒度
        17.4.2 データ分離
    17.5 API層
    17.6 運用面での再利用
    17.7 フロントエンド
    17.8 通信
        17.8.1 コレオグラフィとオーケストレーション
        17.8.2 トランザクションとサーガ
    17.9 アーキテクチャ特性の評価
    17.10 参考文献

18章 適切なアーキテクチャスタイルを選ぶ
    18.1 アーキテクチャにおけるトレンドの変遷
    18.2 判断基準
    18.3 モノリスの事例:シリコンサンドイッチ
        18.3.1 モジュラーモノリス
        18.3.2 マイクロカーネル
    18.4 分散型のケーススタディ:Going、Going、Gone

第III部 テクニックとソフトスキル

19章 アーキテクチャ決定
    19.1 アーキテクチャ決定に関するアンチパターン
        19.1.1 資産防御アンチパターン
        19.1.2 グラウンドホッグデーアンチパターン
        19.1.3 メール駆動アーキテクチャアンチパターン
    19.2 アーキテクチャ上重要なもの
    19.3 アーキテクチャデシジョンレコード
        19.3.1 基本構造
        19.3.2 ADRを保存する
        19.3.3 ドキュメントとしてのADR
        19.3.4 標準のためにADRを用いる
        19.3.5 事例

20章 アーキテクチャ上のリスクを分析する
    20.1 リスクマトリックス
    20.2 リスクアセスメント
    20.3 リスクストーミング
        20.3.1 特定
        20.3.2 合意
        20.3.3 軽減
    20.4 ユーザーストーリーリスク分析
    20.5 リスクストーミング例
        20.5.1 可用性
        20.5.2 弾力性
        20.5.3 セキュリティ

21章 アーキテクチャの図解やプレゼンテーション
    21.1 図解
        21.1.1 ツール
        21.1.2 標準ダイアグラム:UML、C4、ArchiMate
        21.1.3 図解ガイドライン
    21.2 プレゼンテーション
        21.2.1 時間を操る
        21.2.2 段階的な構築
        21.2.3 インフォデッキとプレゼンテーション
        21.2.4 スライドは物語の半分
        21.2.5 不可視化

22章 効果的なチームにする
    22.1 チーム境界
    22.2 アーキテクトのパーソナリティ
        22.2.1 コントロールフリーク
        22.2.2 アームチェアアーキテクト
        22.2.3 効果的なアーキテクト
    22.3 どうやって管理する?
    22.4 チームの警告サイン
    22.5 チェックリストの活用
        22.5.1 開発者のコード完成チェックリスト
        22.5.2 ユニットテストと機能テストのためのチェックリスト
        22.5.3 ソフトウェアリリースのためのチェックリスト
    22.6 ガイダンスの提供
    22.7 まとめ

23章 交渉とリーダーシップのスキル
    23.1 交渉とファシリテーション
        23.1.1 ビジネスステークホルダーとの交渉
        23.1.2 他のアーキテクトとの交渉
        23.1.3 開発者との交渉
    23.2 リーダーとしてのソフトウェアアーキテクト
        23.2.1 アーキテクチャの4つのC
        23.2.2 プラグマティックでありながらもビジョナリーであること
        23.2.3 手本を示してチームをリードする
    23.3 開発チームに溶け込む
    23.4 まとめ

24章 キャリアパスを開く
    24.1 20分ルール
    24.2 パーソナルレーダーの開発
        24.2.1 ThoughtWorksテクノロジーレーダー
        24.2.2 オープンソースのビジュアライゼーションビット
    24.3 ソーシャルメディアの使用
    24.4 別れの挨拶

「合宿」というパターン

今支援させていただいているチームのマネージャーさんが使っていて、とても良いなと思った言葉遣いに「合宿」がある。 ここでいう「合宿」とは、別にチームで泊まりで何かをするという意味でない。メタファーとしての「合宿」だ。

私たちは普段リモートベースで働いているけれど、設計を固めるタイミングなど顔を合わせて詰めた方が良い作業が溜まってくることがある。そうしたときに、「そろそろ合宿しませんか」という言葉が出る。

このチームでの「合宿」とは、みんなで合わせて出社して1日かけて色々な作業を一緒にこなすこと。

単に「出社して一緒に作業しましょう」とかじゃないのが、いいなあと思う。 「合宿」はなんか特別だ。みんなで集まった時間を大事に使わないとなと思う。 集まった日に何をするか、しっかりと意識して過ごせる。

これはリモートがあたり前の時代の、出社のための新しいパターンの1つなのかもしれないな、と感じた。

『ユニコーン企業のひみつ―Spotifyで学んだソフトウェアづくりと働き方』

翻訳を担当した書籍『ユニコーン企業のひみつ―Spotifyで学んだソフトウェアづくりと働き方』(オライリー・ジャパン)が4月26日に発売になります。本書は2019年3月にPragmatic Bookshelfより出版されたJonathan Rasmusson著『Competing with Unicorns: How the World’s Best Companies Ship Software and Work Differently』の全訳です。

本書は、『アジャイルサムライ』(オーム社、2010年)の著者として日本でもよく知られている、Jonathan Rasmussonの3冊目の著作であり、ある時期のSpotifyに身を置いていた著者が、そこでの経験などを元にユニコーン企業のソフトウェアづくりと働き方について解説した書籍となります。

www.oreilly.co.jp

大規模な成功を収めているテック企業(ユニコーン企業)は、スタートアップで機能していたテクニックをエンタープライズ企業レベルにまでスケールさせる方法を見いだし、日々実践しています。AmazonFacebookGoogleなどは、何万人もの従業員を抱えているにもかかわらず、スタートアップのように働いています。本書はSpotifyアジャイルコーチやエンジニアの経験を持つ著者がユニコーン企業のソフトウェアづくりと働き方を解説します。 ミッションによってチームに目的を持たせ、スクワッドに権限を与え、信頼する。カンパニーベットを通じて大規模な取り組みを調整する。このような働き方とそれを実現するための文化のあり方を解説し、複数チームが連携しながら質の高いプロダクトを早くリリースし、迅速に技術革新を行うための方法を学びます。 プロダクトのデリバリーにフォーカスする世界有数のテック企業の事例を紹介する本書は、デリバリープロセスやプロダクト組織自体を改善したいエンジニアやマネージャー、経営リーダー必携の一冊です。

この書籍紹介を読むと、もしかすると「ああなんだ、Spotifyモデルの話か」と思われる方もいるかもしれません。もし、そう思われた方がいたら、いったんその予備知識を傍に置いて、本書を手にとっていただけたら幸いです。そうした捉え方で本書を読んでしまうと、おそらく本書が伝えている大事な部分がこぼれてしまうと考えているからです。

本書は、単に「Spotifyモデル」を解説した本ではありません。本書は、Spotify(をはじめとするテック企業)がどうやってエンジニアリング組織の運営に取り組んでいて、その根っこには何があるのかを捉えようとした書籍です。

目次

本書への推薦の言葉
日本の読者の皆さんへ
お目にかかれて光栄です 

1章 スタートアップはどこが違うのか
    1.1 スタートアップは「火星」から来た
    1.2 「学習する機械」
    1.3 エンタープライズ企業は「金星」から来た
    1.4 「期待に応じる機械」
    1.5 つまり、こういうことだ
    1.6 "Think Different"

2章 ミッションで目的を与える
    2.1 プロジェクトの問題点
    2.2 これが「ミッション」だ
    2.3 ミッションはチームの自発性を高める
    2.4 ミッションは目的を意識させる
    2.5 ミッションは仕事そのものにフォーカスさせる
    2.6 ミッションの例
    2.7 目的を与えよう

3章 スクワッドに権限を与える
    3.1 スクワッドとは?
    3.2 スクワッドはどこが違うのか?
    3.3 プロダクトマネージャー
    3.4 データサイエンティスト
    3.5 分離されたアーキテクチャ
    3.6 自律、権限、信頼
    3.7 経営リーダーのためのヒント
    3.8 Q&A
    3.9 権限を与える

4章 トライブでスケールさせる
    4.1 スケーリングの課題
    4.2 スケーリングの原則
    4.3 トライブ、チャプター、ギルド
    4.4 トライブ 
    4.5 チャプター 
    4.6 ギルド 
    4.7 どこで働きたい?
    4.8 Q&A
    4.9 スケールは大きく、チームは小さく

5章 ベットで方向を揃える
    5.1 しおれた百の花
    5.2 カンパニーベットとは 
    5.3 カンパニーベットの仕組み
    5.4 この働き方の見事なところ 
    5.5 やり抜くためのコツ
    5.6 ベットに賭けろ

6章 テック企業で働くということ
    6.1 フラット化する世界
    6.2 「何をすべきかを指示するつもりはないよ」
    6.3 お金の使い方が違う
    6.4 「信頼してないの?」
    6.5 すべての情報は基本的にオープン
    6.6 「手伝おうか?」
    6.7 テック企業流の人の動かし方

7章 生産性向上に投資する
    7.1 プロダクティビティスクワッドを編成する 
    7.2 セルフサービスモデルを採用する
    7.3 ハックウィークを開催する
    7.4 技術に明るいプロダクトオーナーを活用する
    7.5 品質に高い期待を持つ
    7.6 社内オープンソースを活用する
    7.7 あらゆるレベルでの継続的な改善
    7.8 フィーチャーフラグを活用する
    7.9 リリーストレインでリリースする
    7.10 技術を「一級市民」として扱う

8章 データから学ぶ
    8.1 どこにでもデータがある
    8.2 プロダクトを計測する
    8.3 A/Bテストで実験する
    8.4 そこでデータサイエンティストですよ
    8.5 データを活用する 

9章 文化によって強くなる
    9.1 会社が違えば文化も違う 
    9.2 Spotifyの文化
    9.3 良い文化ってどんな感じ?
    9.4 核となる信念
    9.5 行動は言葉に勝る
    9.6 スウェーデンっぽさ
    9.7 文化が重要

10章 レベルを上げる:ゆきてかえりし物語 
    10.1 目的で動機づける 
    10.2 思考は戦略的に、行動は局所的に
    10.3 プロジェクトではなくチームに投資する
    10.4 技術を「一級市民」として扱う 
    10.5 もっとスタートアップみたいに振る舞う
    10.6 自律した小さなチームとともに
    10.7 コンテキストもあわせて取り入れる
    10.8 率先垂範のリーダーシップ
    10.9 権限を与え、信頼する
    10.10 「言い訳」を取り除く
    10.11 最後に

訳者あとがき 
索引

Spotifyモデル」と聞くと、あたかもそういう「定まったもの」があるように感じ、それをやる・やらない、それが良い・悪い、といった見方をしてしまいがちです。ですが、Spotifyの人たちは、そういう定まったものをあらかじめ持っていたわけでも、それを定めることを目的に何かをしていたわけでもありません。彼らがしていたこと、そして現在でもしていることは「自分たちにとって最善なエンジニアリング組織運営とはどういうものか」に対する取り組みの試行錯誤(学習と実験)だけです。

事業サイズ、従業員規模、プロダクトの状況、解くべき問題が変われば、取り組みも変わっていきます。つまり、巷で言われているSpotifyモデルとは、彼らのそうした組織運営に対する取り組みの、ある時点でのスナップショットに過ぎません。

本書の内容でそれよりも重要なのは、彼らがなぜそうした取り組みに辿り着いたのか、そして、どんな組織であるからこそそうした取り組みが可能なのか、です。

その鍵となるのは、組織が大事にしている価値、そして文化です。何を価値ととらえ、文化をどう育てていっているのか、そこに「ユニコーン企業のひみつ」があります。

何を自分たちの問題ととらえ、それを解決するためにどういうアプローチを取るのか、そしてそれはなぜか。自分たちは何者なのか。そうした厳しい問いの先に、それぞれの企業の組織運営プロセスは現れます。そして、私たちも、そうした厳しい問いの先で、自分たちのプロセスを見つけていく必要があります。

本書は、そうした手ごわい仕事に向かうにあたってのヒントとなる1冊です。

とはいえ、そこはJonathanの著作。アジャイルサムライよろしく、本書も楽しく読める一冊に仕上がっています。

本書は、前書きのこんな結びとともに始まります。

"READY PLAYER ONE?"

VRゴーグルをつけて、いざユニコーンの住む世界へ。深刻になり過ぎずに楽しく読んでいただけたら幸いです。

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

翻訳を担当した書籍『モノリスからマイクロサービスへ ―モノリスを進化させる実践移行ガイド』(オライリー・ジャパン)が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