Closed29

「ソフトウェアアーキテクチャの基礎」読書感想

ピン留めされたアイテム

2010年代を乗り越えてきた経験者が読むと良さそうという噂を聞いたので読んでみた。

https://www.oreilly.co.jp/books/9784873119823/

内容まとめではなく感想です。各章のタイトルだけは丸々記載してますが、目次として上記ページで全て公開されているものです。

ちなみにこれ書いている私はソフトウェアアーキテクトではなく、フロントエンドアプリケーションの設計を担当するテックリードぐらいのレイヤーです。この書籍の中でいう「開発者」です。
業務ではフロントエンドアプリケーションの設計・実装をしています。

ピン留めされたアイテム

全体的な感想

1章(イントロダクション)、22章(効果的なチームにする)、23章(交渉とリーダーシップのスキル)が特によかった。
やっぱ "結局人" の部分が刺さってしまう。

心に書きとめておきたい3つを挙げるとしたら以下。

  • ソフトウェアアーキテクチャとは「構造」「アーキテクチャ特性」「アーキテクチャ決定」「設計指針」の4つから成る
  • 「一見どう見えようとも、それはつねに人の問題」
  • 「プラグマティックでありながらもビジョナリーであること」

これは今の仕事であるテックリードにも十分に活かせることだと思った。

他の箇所は、違う職種のお仕事を覗き見する感覚があって、そこにちょっと情けなさもあった。フルスタックに見れていたらもっと自分ごととして捉えられたと思うのでね…
でもどうしてもユーザー境界のところが好きだから、フルスタックになりたいみたいな気持ちはあんまりないんだよなぁ。それは趣向なので仕方ない。
一方でマイクロフロントエンドとか考えていくときには活かせそうだし、モノリシックフロントエンドやるにしても他領域のメンバーが使う概念や言語を浅くでも理解できたことは良かった。

あと今スタートアップに創業からいて、CTOの仕事を近くで見れているからこそ理解できた記述も結構あった感じがする。スタートアップのCTOと大企業のソフトウェアアーキテクトって要求される事柄に近しいところがあるっぽいなという印象を受けた。ビジネスステークホルダーからの信頼を得るとか、交渉力とかもそう。

1章 イントロダクション

この本の前提となる考え方とか。
特に以下は、「はじめに」とこのイントロダクションで繰り返し説かれている。

  • ソフトウェアの世界は変化し続けている
  • であるなら、今までソフトウェアアーキテクチャが語られるときに前提とされていた事柄も見直すべき
  • ソフトウェアアーキテクチャは一度解決すれば終わりの静的な問題ではなく、動的な問題である

1.1 ソフトウェアアーキテクチャの定義

「ソフトウェアアーキテクチャとは?」に対する著者らの定義が書かれていて、ここの分解がとてもよかった。

私たちは、ソフトウェアアーキテクチャを、システムの 構造 、システムがサポートしなければならない アーキテクチャ特性 (-ility) 、 アーキテクチャ決定 、そして 設計指針 の組み合わせで構成されるものだと考えている。

そのあとこの4つの説明が図と共に続くけど、各図のキャプションが簡潔で的確な説明になっていて良い。

この整理の仕方を知れただけでも読んだ価値あったなと感じた。
今まで自分がアーキテクチャについて考えたり情報を見聞きするとき、この4つをごちゃまぜにしてふわっとしたひとつの「アーキテクチャ」として扱っていたけど、この整理があると自分が何について考えようとしているのか/考えなければならないのか明確になる。
社内向けに作ってるアーキテクチャ紹介資料とか、この軸で整理していきたいなと。

関係ないけど、アーキテクチャ決定の説明内にあった「ほとんどの組織には、アーキテクチャ審査委員会やチームアーキテクトが仕様する特例モデルが存在する」からの一節はちょっとカルチャーショックを受けた。そんな委員会ある会社いたことないし周りでも聞いたことない…これは地域による先進度合いのギャップなのか、単に自分が関わってきた組織規模のギャップなのか。。

1.2 アーキテクトへの期待

これもまたよかった。8つの期待が箇条書きされ、それぞれについて解説されている。
ここで、うしろ3つがソフトスキル的な部分だったのが印象的。

特に7つ目「対人スキルを持ち合わせている」では 「一見どう見えようとも、それはつねに人の問題」 という言葉が別書から引用され、以下の段落に続く。

この業界にはソフトウェアアーキテクトが溢れており、限られたアーキテクトのポジションを奪い合っている。優れたリーダーシップと対人スキルを持つことは、他のアーキテクトと差別化し、一歩抜きん出るための良い方法だ。著者らは、優れた技術者でありながら、有能なアーキテクトとはいえないアーキテクトをたくさん知っている。その原因は、チームのリードや開発者の指導、アイデアやアーキテクチャ決定、設計指針の伝達などがうまくできないことにある。言うまでもなく、そうしたアーキテクトが職位や仕事を持つことは難しい。

昨今はソフトウェア開発者がかなりの売り手市場なので、こういうスタンスの言説は新鮮だった。でもたしかに市場の中でも魅力的で人気のある会社のアーキテクトの椅子は少ないだろうし、後半に書いてあることも完全に "理解る" 。
いや、正直、わかっちゃうからこそ絶望もある。人との関わりが辛くて不得手で、その道は歩まずにプログラミングを熟練させていくことに光を見出していたのに、結局人なのかよと。
でもやっぱり人なんだよな。人々が集まって人々のために作っているのがソフトウェアなんだから。

8つ目の「政治を理解し、かじ取りをする」もつらい。もうそんなの全然やりたくない。
でもここで開発者とアーキテクトの差が示される。
開発者がアプリケーションの一部に特定のデザインパターンを採用する試みは、承認も、チームによってはレビューも要らないものだろうが、アーキテクトが社内システムの結合点のレイヤーを変更するためにインターフェイスを破壊するとしたら、同社内でそこに依存しているすべてのチームから反対されるだろうと。そこに対し(ストレスフルではあるが、)交渉術を駆使して決定を承認してもらう必要があると。

このあたりで、どうやらこの本が語っている「アーキテクチャ」や「アーキテクト」は読む前に私が持ってたイメージよりだいぶ守備範囲が拾い、規模の大きい話なんだなという予感が決定的になった。
なんとなく、自分が普段一番よく携わるアプリケーションを作るときのソースコードのレベルの話をイメージしていたけど、それはさっきの例でいう「開発者」のレイヤーでしかなく、この本が扱う「アーキテクト」はどちらかというとスタートアップでいえばCTO、大企業でいえば◯◯部門技術責任者とかそういうレイヤーの話だなと。

かといってじゃあNot for meなのかというと、逆にそれがよかった。直近薄々感じていた「やっぱり人なのか?」という疑問と、「テクニカルな側面から同じぐらい価値を出すことはできないのか?」という疑問への答えだと思ったから。いやまあ、それなりにしんどい答えではあるけど。
それについての深堀りはここに書くと長くなりすぎるので別で書きます。

1.3 アーキテクチャと交わるもの

エンジニアリングプラクティス について。これは再現性のある、「プロセス(作り方)に依存しない手法」とのこと。ここは前提知識の浅さでだいぶ解像度が低い。元々DevOpsという言葉が指すところもよくわかっていなかったので、XPからの継続的デリバリーからのDevOps、みたいな歴史解説ではへーってなってた。自動テスト・自動デプロイみたいな具体例がでてくるとちょっとわかった気になる。
「アーキテクチャスタイルとエンジニアリングプラクティスには共生関係が存在する」というのが多分肝。

ソフトウェア開発では見積もりが致命的な弱点であること、未知の未知に対しては見積もりも設計もできない、だからプロセスもアーキテクチャもイテレーティブになっていくしかない、というところは実感もあり頷けた。

1.4 ソフトウェアアーキテクチャの法則

必ずトレードオフがあるからこそ、どちらを優先したかについて「なぜ」が重要なんだろうな。
実は今までトレードオフってそこまで感じたことないかも。多くの -ility を上げられるのが良い設計、と思っちゃってるふしがある。フロントエンドアプリケーションに閉じた設計しかしてないからかな。

2章 アーキテクチャ思考

アーキテクチャと設計の違いについて。
そもそもここが違う認識がなかった。1章で得たレイヤーの違いのギャップはこの認識がなかったところからだったんだな。
「従来のアーキテクチャと設計」の図を見るといわゆる上流工程、下流工程って感じ?それをこれからは分断ではなくもっと密にコラボレーションしていく必要があると。

自分の携わるWebアプリケーションでいうと、そもそもWebでやるのアプリでやるの、MPAなのSPAなの、フレームワークはどういうスタイルのものを使うの(リアクティブとか。前章に例があった)、という意思決定がアーキテクチャに近そう。
自分の守備範囲だとSPAまで収束した段階から(SPAでツールを作るのが好きなので、それが適切な意思決定になるような事業・現場を選んでる)なので、設計レイヤーしか知らないのは必然っぽい。ちょっとこの本読むには背伸びしてるか?

アーキテクトと開発者の違いも語られる。開発者は技術の深さが必要、アーキテクトは技術の幅が必要。なるほどな、自分は領域狭めることで深さを担保してる戦略とってるので、逆行している…
というか、ここで認識できたアーキテクトと開発者の違いを踏まえると、自分はどっちになりたいんだろうか?意外と関心から離れていく感覚ある。

トレードオフの分析は設計にも活かせそう。1章ではトレードオフにピンときてなかったけど、ここでの深堀りでだいぶ理解できた。

アーキテクティングとコーディングのバランスをいかにとるか?という話もでてきてるので、やっぱり上流/下流がわかれてるような大規模な現場の話っぽいな。アーキテクトだけしててコードは(書こうとしなければ)書く機会がない、みたいな状況は自分がいた100人程度までの組織だと無かった記憶。

ただ「ボトルネックの罠」はよくわかる。
アプリケーションの基盤的なコードの所有権がテックリードにあり、ただリードポジションだとMTGや他の色々な仕事も多いのでチームのボトルネックになってしまう、という…これはスタートアップでも散見される。というか今私もそう。
そこで基盤をチームに任せて自分は逆に機能開発などをやっていく、っていうのは実際すごく難しく、これをやるにはメンバーの開発スキルの高さと、前章のアーキテクチャ決定・設計指針の明文化と浸透が十分にされていることが必要になってくるだろうな。

3章 モジュール性

モジュール分割して適切に組み合わせていくことが大切なのはわかる。
モジュール性の計測に、凝集度・結合度・コナーセンスという考え方が使える。

凝集度はこのスライドがよかったやつ。 https://speakerdeck.com/sonatard/coheision-coupling
結合度やそのあとは正直だいぶ難しい。式で測れるんだな。「主系列からの距離」は「要はバランス」が可視化されていてちょっと面白い。
コナーセンスは初めて聞いた。凝集度と合わせて覚えたいな。

2章までとうってかわってこの章はかなりコードベースの話をしている印象があった。
実際その点は章の終盤で「これらのメトリクスはコードの低レベルの詳細を見ており、アーキテクチャの構造というよりは、コードの品質と健康状態に焦点を当てているということだ。」と問題点として挙げられている。
逆に "設計" をするときにはこれらの考え方はおさえておきたい。

ここまでの流れ的に、3章にこの内容が挟まるのは若干意外な感じもある。モジュール性という概念のおさらいって感じなのかな。

4章 アーキテクチャ特性

設計/コーディングとアーキテクティングの違いとして、「アーキテクチャ特性」を定義することが挙げられている。
選ばれなかった類義語として「非機能要件」「品質特性」という言葉も出てくる。非機能要件が一番聞き馴染みのある表現かな。

アーキテクチャ特性のリストは参考になった。システムのアーキテクチャということでサーバー間通信やインフラの話が多めになると思っていたけど、アクセシビリティやユーザビリティなどフロントエンド(ユーザー境界)特有のものも挙げられている。特にユーザビリティのところは「ユーザビリティの要件は、他のアーキテクチャ上の課題と同様に真剣に扱われる必要がある」との記載があり、なんだか嬉しさ。
国際標準化機構にも同じようなリストがありそれも記載されていて、このあたりはシステム作るときに参照するとよさそうだなと思った。

そして重要なのは、アーキテクチャ特性同士は競合するので取捨選択が必要ということ。多くをカバーしようとするのはアンチパターン。アーキテクティングはトレードオフという言葉の意味がだんだん染みてくる。

5章 アーキテクチャ特性を明らかにする

前章で触れたようにアーキテクチャ特性はすべてをとれないので取捨選択が必要で、それをどういう軸でやるかという話。
ドメインの関心事、要件、暗黙的な特性の3軸がある。

ドメインの関心事から捉えるアプローチでは、そのドメインではどの特性を重視すべきか?ということで、ここではドメインのステークホルダー(経営者、ドメインエキスパート等)と対話が必要になる。

アーキテクトは、スケーラビリティ、相互運用性、対象外性、学習用意性、可用性について語る。ドメインのステークホルダーは、合併や買収、ユーザーの満足度、市場投入までの時間、競争上の優位性について語る。すると、アーキテクトとドメインのステークホルダーとで会話が噛み合わないという「ロスト・イン・トランスレーション」問題が起こる。

これはあるあるだなと思って面白かった。そこに対して、翻訳となる対応表があるのも面白かった。このあたりはまさに成長フェーズの会社のCTOに求められてきそうなコミュニケーション。

要件から捉えるアプローチでは、アーキテクチャ・カタが紹介されている。要件の例からアーキテクチャ特性を導出してみる演習問題。
実際のカタの問題を題材に著者がアーキテクチャ特性を捉える思考のフローが書かれているので、今既にシステムアーキテクトの仕事に就いている人にはとても参考になりそう。
題材がサンドイッチ屋さんだからランチ時に注文が集中しそう=弾力性が必要だよねとか、親会社が海外展開を予定している=i18nいりそうだよねとか(わかりやすいのをピックアップしてるけど本当はもっと色々)。予測力と対話力が要るのがわかる。
コードベースの設計よりも泥臭くて地道な取捨選択の印象を得た。以下の引用からも感じられる。

アーキテクチャには最高の設計はない。少なくとも最悪でないトレードオフの集合があるだけだ。

6章 アーキテクチャ特性の計測と統制

選択したアーキテクチャ特性をどう計測・統制するか。前段として、各アーキテクチャ特性について組織内で共通の定義を持っておくことが必要。(たとえば、ひとくちにパフォーマンスといっても何を指すのか?)

計測には運用面の計測、構造面の計測、プロセス面の計測がある。
統制には適応度関数を用いて循環依存を見つけたりレイヤーの規約違反を見つけたりなど。

この章は今の自分が実務で意識していることだった。実際に、書いてあることが(方法は違えど)まんま今のプロジェクトでやれてるなという点もいくつかあったし、こういうこともやりたいなというようなヒントももらえた。

今やれていること

  • 計測
    • PRごとにバンドルサイズの増減を自動でコメント(パフォーマンス計測)
  • 統制

今後やりたいこと

  • 計測
    • 実際のアプリケーション動作時のパフォーマンス計測
    • 循環的複雑度の計測(eslint/complexity でできそう)
    • テストカバレッジの計測

うーん書き出すと統制は結構やれてるけど計測はまだまだだな…😂
でも4章5章が自分が全然やれてないレイヤーの話だったので、ここでちょっとやれてる話がきて少し慰められたのは確か。笑

ただやれている部分も「今のプロジェクトにはこういうアーキテクチャ特性が必要だからこれを計測/統制する」という順序立った考えでやれているわけではないので、今後はそういう考えができるといい。

7章 アーキテクチャ特性のスコープ

アーキテクチャ量子という概念が出てくる。独立してデプロイされ、機能的に凝集していて、同期的に接続(コナーセンス)されている。これはマイクロサービスの1サービスみたいなイメージで合ってるのかな?

アーキテクチャ・カタのもうひとつの演習問題。5章のよりだいぶ難易度高め。
これはもう設計やコーディングとはぜんぜん違う職域だなと思った。アーキテクトってこういうことなのか。分業してたらやる機会なさそう…

8章 コンポーネントベース思考

コンポーネントはモジュールの物理的表現。
アーキテクチャを構成するコンポーネントを定義・改良・管理・統制するのがアーキテクトの役割。

8.2.1 アーキテクチャの分割

最上位分割の例としてレイヤードアーキテクチャ(技術的関心で分離)とモジュラーモノリス(ドメインで分離)が比較される。ここでもどちらが正解とかではなく、トレードオフ。ここの判断はアーキテクトが最初に判断しないといけないことの一つ、とある。
アプリケーションコードの分割でも最上位ディレクトリの分割軸を何にするかって結構迷うなと思ったりした。ディレクトリ構造と重ねるのは矮小化だろうなと思いつつ、わりとそこと重ねて読んでた。

フロントエンドアーキテクチャはMVCからの歴史もあってか、技術的関心で区切られるレイヤードな切り方が多めな印象がある。実際私が作ってるアプリケーションも第一階層はそうなってる。
ただそのすぐ下の階層はドメインで区切ると扱いやすいので、 Componentも 他のレイヤーも内側の区切りはドメインになっている。
思い切って上下をひっくり返して第一階層をドメインにしちゃうとかもありなのかもなぁ。その下を同じ構造に保つというコントロールが効かなくなってきそうなのがちょっとあれだけど…むしろチームが大きくなってきたらそこのコントロールも諦めちゃって第一階層もチームもドメインで切っちゃえば両方うまく分割できたり、マイクロフロントエンドとかも考えやすくなってくるのかも。

脱線…

8.4 コンポーネントを識別する流れ

アーキテクティングにもイテレーティブなプロセスが大事と強調される。最初のアーキテクチャは下書き程度に捉えて、フィードバックを得てより精緻なものにしていく。

コンポーネントの識別において大切なのは「粒度」だというのは頷けた。ここが大きすぎても小さすぎても問題がでてしまう。でも最初から適切な粒度を決め打つのは無理なので、イテレーションを回してだんだん照準をあわせていくようなイメージっぽい。まあそうだなぁ。

8.6.1.1 エンティティの罠

アンチパターンの実例。
カタの演習問題からアーキテクチャを組み立てる際、単純にいくつかのエンティティを抜き出し、そこにCRUD的な操作をくっつけるだけではアーキテクチャとはいえないという話。それはただのORMだと。
これはたしかにハマりそうだなと思った。特に通信のインターフェイスがRESTだと引っ張られやすいだろうな。っていうか文中でも触れられているけどRailsのscaffoldとかまさにそうだよね。
ただアーキテクトのニーズがそれでじゅうぶん賄えるならそれでいい(本格的なアーキテクチャは必要ない)とも書いてある。社内向け管理画面とかそうなりがちなやつ。
ただ適切なアーキテクトが他にありそうなのにこの罠にハマっちゃうパターンはマジで身近にありそうだなと思った。

8.7 事例

7章に出てきたカタの演習を使った具体的なコンポーネントの発見例。これもアーキテクトの思考を追っていける感じですごくいい。
ロールとアクションから導かれたコンポーネントに対して、アーキテクチャ特性の分析というステップを踏むことで特定のコンポーネントに分割の必要があることが発見されるところとか見事な感じだった。

8.8 モノリシックアーキテクチャと分散アーキテクチャの選択

これもトレードオフなのでどちらが正しいとかではないが、8.7でアーキテクチャ特性の要求に対してコンポーネントを分割した(片方は信頼性や可用性を高める必要があり、もう片方はそうでない)ので、その場合は必然的に分散アーキテクチャをとる必要があるという話はなるほどだった。モノリシックだとコンポーネントわけても結局同じアーキテクチャ特性になってしまうので。
前の章で出てきた「アーキテクチャ量子はアーキテクチャ特性のスコープを定義する」という話はそのとき全くわからなかったけど、こういうことか、と理解できた。


「第Ⅰ部 基礎」はここまで。なかなか重厚な基礎だった。

そういえば前職のbackendsはこういうアーキテクティングをしていたなぁとイベントストーミングのところで思い出した。証券システムなので扱うドメインが難しいし、マイクロサービスだし、まさにこういう意思決定をしていたんだろうな。フロントはBFF挟んでひとつだったのでそこの意思決定に入っていけなくても業務的にはあまり困らなかったけど、今思えばもっと首を突っ込んで色々聞いていればよかった。

ここから 第Ⅱ部 アーキテクチャスタイル に入る。具体的な各アーキテクチャスタイルの紹介。

9章 基礎

アーキテクチャスタイルの基礎。デザインパターンのアーキテクチャ版。
優れたアーキテクトは、アーキテクチャスタイルの名前から、その背景にある構造・アーキテクチャ特性のサポート有無・デプロイメントモデル、データ戦略などを想像できないといけない。なるほど。

基礎パターンとして歴史上の変遷を軽くおさらい。

9.2 モノリシックアーキテクチャと分散アーキテクチャ

分散アーキテクチャの課題として、「分散コンピューティングの誤信」の8つを紹介。
その他考慮事項のところではもっと具体的で実務的な課題にも触れられている。
読んで理解できる程度の下地はあってよかった。
分散アーキテクチャはデータの整合性や完全性を犠牲にすることで、スケーラビリティやパフォーマンスや可用性を実現している。これもトレードオフ。

10章、11章、12章はモノリシックアーキテクチャの紹介。

10章 レイヤードアーキテクチャ

モノリシックアーキテクチャに分類される。一番基本的なスタイルとして紹介されている。たしかに一番馴染みがある。
シンプルだしコンウェイの法則的にも多くの組織の形と合っているので馴染みやすいが、アジリティの欠如が弱点。
各ドメインが各レイヤーに点在することになるのでDDDと相性が悪いとある。そこはそんなに認識してなかった。

まず初手でレイヤードアーキテクチャで様子見るケースは多いが、その場合は再利用を最小限に抑えて適切なモジュール性を維持しておこう、そうするとあとで他のアーキテクチャスタイルへの移行が楽、とある。これはなんかわかる。コードベースでも同じ話だと思う。1レイヤーの中で同じような処理が多いからってドメイン横断で共通化しちゃうとあとから身動きとれなくなるので、わたしも避けがち。

ザ・モノリシックアーキテクチャなのでこのまま大きくなっていくと保守性・アジリティ・テスト容易性・デプロイ容易性などでつらみが増してくる、というところはフロントエンドアプリケーションでもイメージがつく。マイクロフロントエンドが叫ばれ始めた背景も似通っているのではないか。

アーキテクチャ特性評価は、レイヤードであること起因が半分、モノリシックであること起因が半分ぐらいの印象。

11章 パイプラインアーキテクチャ

bashとかmap/reduceとかの。JS書きなので馴染みはあるけど、ソフトウェアアーキテクチャっていう大きい文脈でも出てくるんだーというのは意外だった。
事例としてKafkaからmongoDBへデータを処理するシステムが挙げられている。たしかにデータ流すところとかだと相性よさそうだしイメージしやすい。

アーキテクチャ特性評価は、レイヤードアーキテクチャに比べてモジュール性が高まっていることにより進化性、デプロイ容易性、テスト容易性も少し上がった感じ。それ以外は結局モノリシックなので一緒。

12章 マイクロカーネルアーキテクチャ

このプラグイン方式のやつがマイクロカーネルアーキテクチャって名前なんだ。そっち側の知識薄くて知らなかった…(プラグインアーキテクチャとも呼ばれる、と書いてある)
フロントエンドだとビルドツールとかで頻出パターン、webpackもそうだよね。

コアシステムとプラグインコンポーネントから成る。コアシステム内部は技術で分割(レイヤードコアシステム)することも、ドメインで分割(モジュラーコアシステム)することもできる。両方選択可能な唯一のアーキテクチャスタイルとのこと。
コアシステムとプラグインコンポーネントの結びつきは、静的な場合もランタイムの場合もある。

プラグインコンポーネントとはリモートアクセスで繋ぐようにしてスタンドアロン化することもできるが、そうしたとしても必ずコアシステムから入らないと使えないので、アーキテクチャ量子としては変わらず1のまま。ただ複数のプラグインとのやりとりを非同期でできるようになるとレスポンス性能は改善する可能性もある。
ただプラグインをリモートアクセスで繋ぐと分散アーキテクチャの形になるので、分散アーキテクチャのトレードオフが入ってくることになる。

事例としては保険金請求処理や税務申告書作成など、地域ごとにローカルなルールが点在するドメインが挙げられていて、たしかに相性がよさそうと思った。(その組み合わせ爆発をモノリシックなレイヤードアーキテクチャでまかなおうとするとやばいことになるのは想像に難くない)

13章、14章、15章、16章、17章は分散アーキテクチャの紹介。
モノリシックアーキテクチャの紹介と比べてページ数が3~4倍ぐらいある…

13章 サービスベースアーキテクチャ

とても人気で最も実用的なアーキテクチャスタイルのひとつとのこと。
デプロイ単位がサービスごとにわかれていて、DBは共通もしくはサービス間で通信しなくてもいい単位で分割。
あれマイクロサービスってこれとは違うんだっけ?と思って先の章と比べたら、大きくはサービスごとのDBの有無と分割粒度が違うっぽい。理解の浅さが出てる。
決済した場合などの具体的な例が書いてあるので、どういう分割粒度の違いなのかイメージがわきやすい。

サービスベースアーキテクチャではドメインサービス間の通信は絶対に避けるべき、とある。DBが一緒なのでそっちに任せるべきって感じかな。たしかにUIもサービスもDBも横に繋がってたら分散の意味あんまりないかも。あるサービスが落ちても他のサービスは生きてる、っていうメリットも活かせないし。

ひとつのサービスの内側はレイヤード設計かドメイン設計が挙げられてる。やっぱり最上位の分割はこのふたつに収束していくのか。

物理的にはDBはひとつだが、変更の影響範囲が大きくなるので、DB内部を論理的に分割してそれぞれを少ないサービスと対応させていくことがリスク軽減の方法として紹介されている。

「アーキテクチャ量子」の理解がふわふわしてたけど、図13-10でわかった。DB-サービス-UIまで含まれて1量子になっている。独立して動作する1単位みたいな?(っていうことが定義のところにも書いてあったと思うが、理解できてなかった)

サービス間でDBを共有してるから、サービスベースアーキテクチャは分散アーキテクチャでありながらACIDトランザクションを保持できる。コミットやロールバックができる。

14章 イベント駆動アーキテクチャ

高度にスケーラブルで高パフォーマンスなアプリケーションを実現するための分散非同期型のアーキテクチャスタイル。

最初のほうにリクエストベースモデルとイベントベースモデルの話が出てきてるけど、これは両方イベント駆動アーキテクチャの中での話なのか、それとも後者がイベント駆動アーキテクチャを指しているのか…
このへんからだんだん理解が及ばなくなってくる。

ブローカーとメディエーターというふたつの主要なトポロジーがある。(トポロジー、形、ぐらいのニュアンスでしか受け取れてない)

14.2 ブローカー

ブローカートポロジーは各イベントプロセッサーがピタゴラスイッチみたいな感じで動くので高度に独立しているが、そのぶん全体を通した完了や失敗を知ることができない。どこかが落ちても動き続けられるのは強みでもあり弱み(データの不整合が起きうる)でもある。
ブローカートポロジーの処理イベントはイベント(既に起こったこと)であり、無視することもできる。(無視というか受け取るイベントプロセッサーがいなくてもいいみたいな感じかな)

14.3 メディエーター

メディエータートポロジーはイベントメディエーターというのが中心に登場して、そいつが各イベントプロセッサーへイベントを送り、完了を受け取る。メディエーターはドメインのグループごととかイベントのグループごとに複数存在しうる。(ひとつだったらSPOFになるしけっこうモノリシックな印象になるもんな)
メディエーターは色々な種類(製品?OSS?)があるっぽい。求められる複雑度に応じて適したものを選定する、もしくは複数種類のメディエーターを採用して、単純なイベントは単純イベント向けメディエーターで処理し、複雑なやつは複雑なイベント向けメディエーターにパスする、みたいにするらしい。だいぶ複雑。図も半ページ以上使うようになってきてるw
メディエータートポロジーの処理イベントはコマンド(起こるべきこと)であり、処理される必要がある。

14.4 非同期の能力

イベント駆動アーキテクチャのユニークな特徴は、非同期通信にのみ依存していること。
非同期通信でもRESTのように「リクエスト/リプライ方式」(疑似同期)でレスポンスを待って次に進む場合もあるが、「ファイア・アンド・フォーゲット方式」で投げっぱなしにしてOKとすることもできる。後者の場合はパフォーマンスはとても上がるが、最終的に処理が完了することは保証できないし、完了しなかった場合にその場でユーザーにフィードバックはできない。

14.5 エラー処理

ワークフロープロセッサーという登場人物を使ってエラーから回復する方法が書かれている。あるイベントを処理しているイベントプロセッサーでエラーが起きたら、ワークフロープロセッサーへそのイベントを回し、ワークフロープロセッサーはそのイベントのエラーを解析して修復してからまた元のイベントプロセッサーへ流す。
これすごく面白い。自動で解析して修復して、みたいなことができるんだ。機械学習アルゴリズムを活用することもあると書いてる。すごい生きてる感じ。

自分が実装する範囲だとエラーの修復を自動でやるとかは全然ないな。でも考えたらエラーレスポンスに対して「リクエストの内容をこう直せば通る」がわかっているのであれば勝手に直してもう一度投げ直すのはアリだよな。ただ普通に実装してると「投げ直す」はcallbackでまたその関数呼ぶの?みたいな感じで結構大変だけど、イベントベースで繋がっていればやりやすい=reduxならmiddleware内で特定actionもう一度投げればいいよね、みたいな感じかも。

15章 スペースベースアーキテクチャ

高いスケーラビリティ、弾力性、同時実行性を目的にしたアーキテクチャ。たとえばチケット販売システムやオークションシステムなど、特定タイミングで一気にアクセス数が跳ね上がるようなサービスに向く。
通常サービスの負荷が上がったらスケールアップしていってもDBのスケールアップが難しく限界がきてしまうが、そこを各ユニットのメモリ内にデータを持ちながらDBの読み書きは非同期ですることで、無限のアプリケーションのスケーラビリティを得られると。インメモリ!そんなやりかたがあるのか…

以下なるほどって思ったことメモ

  • 処理ユニットごとにインメモリデータグリッドを持ち、そこにDBデータのキャッシュがある状態
  • DBへはデータリーダー/データライターを介して非同期にアクセスし、変更があればその結果がまた全処理ユニットのデータグリッドにレプリケーションされる
  • DBへの接続が非同期なので、アーキテクチャ特性はDBからくる制限から開放される
  • データリーダー/データライターはデータ抽象層になれるので、DBの構造と処理ユニットのメモリのデータ構造を異なるものにできる
  • データ抽象層とDBをオンプレに起き、それ以外をクラウドに置くことで両方のいいとこどりをすることもできる
  • レプリケーション中のデータ衝突による不整合は起きうるが、確率を計算できる
  • 各処理ユニット間のレプリケーションは高速であり、全処理ユニットにデータキャッシュがあるのでSPOFが存在しない
  • デプロイされる仮想マシンにはメモリ上限があるので、存在できる処理ユニット数にも上限がでてくる
  • 処理ユニットにレプリケーションキャッシュを持たず、外側にキャッシュサーバーを持つ分散キャッシュという方法もある(各処理ユニットに持ってるほうが "分散" 感あるけど…)。データ一貫性が上がるかわりにパフォーマンスや耐障害性が下がる。どちらをとるかはどのアーキテクチャ特性を優先したいかによる
  • スペースベースアーキテクチャの分割タイプは面白い。各処理ユニットはドメインで分割できる一方で、そうしたとしても処理ユニット/データポンプ/データリーダー・ライター/DBという技術的なレイヤー分割もされている(レイヤードアーキテクチャに似ている)。両方が重ね合わさった形かもしれない。

DBデータのキャッシュをメモリ内に作ることで無限のスケーラビリティを得られる…最終的なボトルネックがDBになることは薄々イメージついてたけどこういう避け方があるとは知らなかった。たしかにチケット予約とか、アクセス殺到するサービスで全部DBまでそのまま疎通してたら無理だよな…

16章 オーケストレーション駆動サービスアーキテクチャ

これは歴史上の遺物っぽい…?実際説明を読んでもこれだけ全然どういうことかわからない。。。
アーキテクトの分野でやっている方はこの時代経験してなくても説明で想像はできるのかもだけど、専門外から歴史まで想像するのは遠すぎた😇
実際文中でもこのアーキテクチャから教訓と学びを得て今のアーキテクチャがある、みたいな感じで現役のアーキテクチャではないようなので流しておく。

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

ついにきた!よく聞く代表。ドメインとか責務ごとに細かくサーバーがわかれてる、ぐらいの極ふわっとした理解しかない…
マーチン・ファウラーのブログから火がついたんだ。かっこいいですね。フロントでいうと初めてFluxが語られたセッションみたいな?
DDDから影響受けてるんだな。分割点は単にドメインというわけではなくて「境界づけられたコンテキスト」とあるから、想像以上にDDDの設計をそのままシステムに映した形になっているっぽい(DDD詳しくないが)

粒度の設定が肝ということで、そこはアーキテクトも苦心するところっぽい。サービスを小さくしすぎてしまうことが多いと。すごいな、小さくするほうが大変そうだけどそっちに寄るんだ…
ひとつの指標として、サービスをまたがずにトランザクションできる単位、というのがある。

マイクロサービスではサービスごとにDBを持つ。ここでもエンティティの罠が出てくる。たしかに単にエンティティごとにサービスがわかれててそれぞれCRUDだけ生えてます、って感じだったらなんか無駄に通信だけ増えて微妙そう。
マイクロサービスの場合は1DBが扱うデータの範囲も小さくなるから、望ましいテーブル設計とかデータ設計のやりかたも変わるのかな。
DBが分割されるのでサービスによって適切なDBの種類やツールを選べるというメリットがある。

マイクロサービスにはメディエーターやオーケストレーションの層を設けないほうがいい。技術による分割をされたアーキテクチャならそれらを使うのが一般的だが、ドメインによる分割をされたアーキテクチャでは(哲学に忠実でありたいのなら)必要ない、とのこと。

マイクロサービスは共通化を避け重複を許容したアーキテクチャだが、ロギングやモニタリングなどすべてのサービスに共通するような「運用面」の関心事はサイドカーパターンで共通化することができる。

17.7 フロントエンド

おーモノリシックフロントエンドと並んでマイクロフロントエンドが紹介されている!
マイクロサービスの当初のビジョンではDDDの原則に忠実にUIも境界で分割するのが望ましい感じだったらしい。
マイクロフロントエンド…うまくやれてるところあるのかな?数年前結構盛り上がってたけど最近あんまり聞かなくなっちゃった印象。
ただうちのプロジェクトでは Componentの分類をドメインでやるとやりやすい のは感じてるので、図みたいな構造へはもっていきやすい現状になってるかも。

17.8.1 コレオグラフィとオーケストレーション

コレオグラフィって言葉がわかってなかったけど、イベント駆動アーキテクチャのブローカーのところで「ピタゴラスイッチみたいに」って思ったのがそれっぽい。中央不在でそれぞれのノードが動いていくスタイル。 コレオグラフィパターン
オーケストレーションと対になる言葉。

マイクロサービスでもこのふたつを選択することができる。
コレオグラフィでいくとしたら、APIから最初に呼び出されたサービスが他のサービスを順番に呼び出したりなどの実質的なコントローラーの役目も担うことになる。(フロントコントローラーパターン)
オーケストレーションでいくとしたらメディエーターを自作する。コントローラーの役目は分離できるが新たな結合が生まれる。これもトレードオフ。

17.8.2 トランザクションとサーガ

マイクロサービスでサービスをまたいだトランザクションをするのはアンチパターンでなるべく避けるべき。
だが、アーキテクチャ特性が異なるサービス(=サービスわけざるを得ない)でありながらトランザクションは必要、みたいなケースがないこともない。
そういうときに使える分散トランザクションのパターンのひとつがサーガパターン。メディエーターに補償トランザクションを頑張ってもらう。


マイクロサービスの解像度はだいぶ上がった。実践してないのでわかった気になってるだけだけど。

  • サービスひとつひとつが単独で動ける単位になっている(=アーキテクチャ量子とほぼ同じ)
  • 分割の単位は「境界づけられたコンテキスト」

13章のサービスベースアーキテクチャのとき似てるなと思ったけど、振り返ると違いがよくわかるようになった。

関係ない脱線話:

マイクロサービスのところに書いてあった

再利用はたしかに有益だ。しかし、トレードオフに関するソフトウェアアーキテクチャの第一法則を思い出して欲しい。再利用は結合という負のトレードオフをもたらす。

アーキテクトの目標が高度な分離を必要とする場合には、アーキテクトは再利用よりも複製を優先する。

これめっちゃわかるってなった。

私も若い頃はなんでもDRYにすればするほどいいと思って、やたら複雑なことしながら似てる処理を共通化して、頭いいことできたぞ〜と悦に浸って、あとから特定のどれかだけに変更を入れたいみたいなことができなくなって詰むみたいなことを繰り返していて(設計とか好きな人なら駆け出しのときみんな通る道だよね?😂 )、今ではわりと分離のほうに寄せた意思決定をするようになった。
ただその方針でやってると「ここ何度も似たようなこと書いてるからまとめたほうがいいんじゃない?」っていう指摘を受けることもあって、そのたびに過去の経験ベースで意思決定の理由を説明してたんだけど、単に「再利用には結合っていうトレードオフがあるので、結合を避けたいんですよね」って説明すればよかったのか。
なんかやっと「アーキテクチャはトレードオフ」っていうのが脳に染み渡ってきたな。

ちなみに重複してでも分離をとることが戦略であると学べたのはECSSの概念に触れたときだった。

18章 適切なアーキテクチャスタイルを選ぶ

アーキテクチャ選択でトレンドを読むのが重要、といわれるのは意外な気がした。フロントはトレンド敏感な傾向だけどそれを揶揄されることも多かったりするからか、システムアーキテクチャとかだとトレンドに左右されない基本があるみたいな感じの印象があった。
でもたしかにソフトウェアアーキテクチャの世界でもKubernetesとかDockerとかでガラッと変わったりしたわけだよね。
新しい能力 の例にはまさにそのDockerのようなコンテナ技術が挙げられている。

アーキテクトは、新しいツールだけでなく、新しいパラダイムにも目を光らせておかなくてはならない。一見すると、すでにあるものと同じように見えるかもしれないが、ニュアンスやその他の変更点が含まれていて、それがゲームチェンジャーになるかもしれないからだ。新しい能力は、開発の世界全体を揺るがすようなものでなくても、アーキテクトの目標にぴったりあったマイナーチェンジであってもよいのだ。

ここなんかよかったな。ここ読んで頭に浮かんだ直近のことはReact SuspenseとSWRかなー。Suspenseでの同期的非同期処理は自分にとってはパラダイムシフトだと思った。マイナーチェンジであったとしても。
立ち上げ時にbetしてここまでそれで作ってきてよかったなと今振り返って思う。

アーキテクトとしての選択、モノリスか分散か?データをどこに置くか?通信は同期か非同期か?
判断の背景をADRにするだけではなく、とりたいトレードオフをとれているかというのをアーキテクチャ適応度関数に落とし込むことで運用中もそのアーキテクチャの恩恵をチェックし続けられるというのは学び。

2種類のアーキテクチャ・カタのアーキテクチャスタイル選定の話が書いてある。BFFも紹介されている。(別にマイクロカーネルでしかとれない選択肢ではないよね?モジュラモノリスでもできそうな…)

ここから 第Ⅲ部 テクニックとソフトスキル に入る。

19章 アーキテクチャ決定

アーキテクチャ決定は、ソフトウェアアーキテクチャの定義である「構造(アーキテクチャスタイル)」「アーキテクチャ特性」「アーキテクチャ決定」「設計指針」の3番目の項目。

まずはアンチパターンをおさえていく。
紹介されている3段階のアンチパターンが「決められない」「根拠が残されておらず何度も議論してしまう」「決定が伝わっていない」だったのが意外だった。なんかもっと「◯◯というアーキテクチャ特性を実現しようとして☓☓の方法をとるのは実は△△のような実害のあるアンチパターンである」みたいなことかと思った…
決められないとか同じこと何度も議論するとかって、実際ありがちだけど、なんかそれってスタートラインにすら立てていないような感じで、こういう技術書を書くような海外のアーキテクトの周りではそもそも起こらない低レベルな問題なのかと思っていた。アンチパターンといえるぐらい、どんなレベルの人達の間でも起きうることなんだなぁ。

アーキテクチャ決定の根拠を示す際には、技術的な理由とビジネス的な理由の両方を提示することが重要だ。

どちらが欠けてもダメ、またビジネス的な理由はビジネスステークホルダーが重視している点と重なっている必要がある、と。ここでもアーキテクトに事業理解が求められることがわかる。

ADRの書き方が結構ガッツリ紹介されている。私も昔koba04さんに社外レビューしてもらった際に教えてもらった。コードレベルの選択だとまだあんまり書けてないんだけど、アプリケーションをスマホ対応するときにどういう方法でスマホ対応するかの決定のADRを書いたな。(フォーマットはそんなにかっちりできていないけど…)
思い返したらあれが一番アーキテクチャ決定っぽい仕事だったかもしれない。
あとうちのエンジニアチームだと主にbackendメンバーがよくDesign Docという設計文書を書いていて、あれが一番ADRに近そう。データ部分とか一度走り出すとあとから変えるの大変だし。

HowよりもWhyを書くって、わかってるけどなかなかむずかしいんだよなぁ。単純に忘れてるほか、Whyに対するHowへの自信が欠けているとWhyを堂々と書けながちだったりするのかも。
文末も「◯◯にするのがいいと思う」ではなく「◯◯を使用する」と表現しようとある。

ADRの「コンプライアンス」セクションのことは初めて聞いた。
そのアーキテクチャ決定を守れていることをどのようにチェックするか、みたいな。
適応度関数を作って自動でチェックするならその関数の内容、または手動でチェックするならどう手動でやるのか?みたいなことか。これも決定のタイミングで同時に考えられるのはいいな。

最後のADRの例はとても簡潔でわかりやすい。「コンテキスト」で先にやりたいこととその実現選択肢を提示して、「決定」でどれを選んだかとその理由、っていうフォーマットは汎用性があって良いな。

20章 アーキテクチャ上のリスクを分析する

影響度×発生可能性でのリスクマトリックスは社内のインフラ/セキュリティのロードマップでも使われていたな。
先に影響度を考えてから可能性を考えよう、っていうTipsは初めて聞いた。先に可能性考えちゃうとそのあと影響度考えるときに引っ張られちゃうから?

リスクアセスメントは上記リスクマトリックスでの数値算出をドメイン(サービス)×リスク基準ぶんおこなう。リスク基準はアーキテクチャ特性に似てるな。さらに一度算出されたリスクアセスメントはその時点でのスナップショットでしかないので、時系列でどう変化しているかという奥行きの情報を加えるのも効果的と。つまり運用段階でも定期的にやっていく営みなんだな。

リスクストーミングはアーキテクチャ図に対してリスクアセスメントを複数人で評価していくが、一度の会ではひとつのリスク基準(パフォーマンスならパフォーマンスだけ、など)にフォーカスしてやるべきと…全体の合意までいくのにかなり時間がかかりそう。そんなに丁寧にやるんだ。多分イメージしてるサービスの規模が、自分が今まで関わったことないぐらい大規模な感じなんだろうな。。

リスクストーミングの特定フェーズで、自分が未知の技術(例:Redisキャッシュ)に対して高リスクの付箋を貼るとよい、っていうのは結構びっくりした。そのあとの合意フェーズで自分にとって未知であることを共有して、軽減フェーズでは説明とかがおこなわれるのかな?すごい寛大、というか心理的安全性。でもそうあるべきだよな。
軽減フェーズではリスク軽減の方法を議論するほか、そこに追加コストがかかる場合もあるのでビジネスステークホルダーも巻き込んでトレードオフを議論するとある。この本、ずっとビジネス視点のことを切り離せない(切り離すべきでない)ものとして書いていて、仕事としてのアーキテクトについて書かれた本だなと思う。技術記事だとあんまりそういう視点までは含まれないよね。

リスクストーミングがシステムアーキテクチャだけでなくユーザーストーリーにも使えるって話は面白い。多分スタートアップの1機能ごとのユーザーストーリーだとtoo muchだけど…他社との合同プロジェクトみたいなのだと合うかも。

リスクストーミング例めっちゃおもしろい。この本、全体的にどのセクションも理論が書かれたあとに実例があって、そこですごくイメージがつくのがいい。
セキュリティのリスクストーミングの例見ながら、あー前にあったomni7の脆弱性の類とかもこういうプロセスがあったら気付ける確率上がるんだろうなぁ、と思ったりした(あれは単にプロセスの問題だけではないんだろうけど…)

21章 アーキテクチャの図解やプレゼンテーション

アーキテクトには図解スキルが必要!
たしかにチームで仕事すればするほど、仕事における情報伝達の重要性と、情報伝達における視覚的要素の重要性が身に染みてくる。集団で何かを作る仕事なら、アーキテクトだけじゃなくどんなポジションでも役立つスキルだと思う。

オムニグラフ、コンフルでサポートか拡張があるやつだっけ?前職で触れてたようなうっすらな記憶…
自分が設計を図解するときはWhimsical使ってる。サービス名のスペルが難しいことを除けばめっちゃいいツール。miroより好き。

一般に、アーキテクチャ図に存在する数少ない標準として、実線は同期通信を、点線は非同期通信を示す。

そうなんだ…

21.2 プレゼンテーション

アーキテクトにはプレゼンスキルも求められる。
同じ著者が前に、ソフトウェア業界でのパターンやアンチパターンをプレゼンテーションに応用したPresentation Patternsっていう本も出したらしい。

この章けっこうおもしろい。

  • ドキュメントとプレゼンテーションの違いは、発表者と視聴者どちらが 時間 をコントロールできるか
    • なのでプレゼンでは発表者が時間を操ることがとても重要
  • プレゼンでは言語と視覚という2つの情報チャンネルがある
    • スライドにたくさんのテキストを配置して、声ではそれを読み上げるだけだと視聴者はまず話聞かずに文字読むし読み終わったら退屈する
      • これ、わかってるけどまじでやりがち
    • 話にあわせて段階的に情報を表示するとよい
    • 非同期に読んでもらうためのスライドはプレゼンテーションではなくインフォデッキという。それなら情報が網羅されていてもいい。
    • プレゼンテーションの場合はスライドに情報を網羅せず、意図的に半分だけ役割を負わせる。もう半分は発表者。
  • 不可視化というテクニック
    • プレゼンテーション内に空のスライドを挟んで話者に注目させてから声でメッセージを伝えるテクニック
      • これまさに先日社内のシニアなbizメンバーがやってた!

多分この章に興味あるソフトウェアエンジニアあんまり多くないんじゃないかな…こんなん考えるぐらいならコード書いてたいみたいな。
私は技術特化型じゃないぶんコミュニケーションスキルとかも組み合わせて価値出しているタイプなので、こういう話は結構惹かれる。あと今社内に手練のビジネスメンバーが多くて、そういうメンバーはこのあたりは息をするように実践してるので、実例が思い浮かびやすいっていうのもある。
自分はビジネス書はあんまり読まないけど、こういうの面白がれるってことはそういう本読んでみてもいいのかもな…なんか質がピンキリそうであんまり手が出ないんだけど。

関係ないけど

トランジションはスライドからスライドへと移動する操作、アニメーションはスライド内に動きを作り出す操作だ。

この説明、CSSのtransitionとanimationの説明にまんま使えるな…
transitionはセレクタからセレクタへの移動に時間経過が加えられて発生するもので、animationはひとつのセレクタ内に動きを作り出すもの。
同様の理解はもともと持ってたんだけど言語化がうまくできてなかったので、ヒントになった。

(しかし自分がプレゼンテーションでtransition/animation使うことはほぼない)

22章 効果的なチームにする

22.1 チーム境界

チームとの関わり方について。開発者に対しての制約を厳しくしすぎるコントロールフリークアーキテクト、緩すぎて自身の責任を果たしていないアームチェアアーキテクトが紹介されている。
私はコントロールフリークになりがちなタイプなのを自覚している。

さらには、開発チーム向けに擬似コードを書くことまでするかもしれない。

これ稀にコードレビューでやっちゃうんだよな…suggested changesを超えた粒度で。
言葉で説明すると、意図が伝わらなかった場合に修正後のコードに対してまたフィードバックしなきゃいけないことに気後れして、意図が必ず伝わる形でって考えるとコードになっちゃう。
でも最近はそれで実装がスムーズに進んだとしても他の害のほうが大きそうだなって思って言葉での説明に留めるほうに倒している。別に1文字1文字指定したいわけではないし。

本質的に、コントロールフリークアーキテクトは、開発者からプログラミングの技術を奪う振る舞いをする。それは結果的に、フラストレーションやアーキテクトに対する敬意の欠如をチームにもたらすことになる。

これは本当にわかるので。
言葉で伝えて納得してもらった上で、そのエッセンスをレビュイーの手で自分のコードとして書いてもらうことが、モチベの面でも技術継承の上でも重要だよな。

ちなみにコントロールフリークアーキテクトもアームチェアアーキテクトも、両極だとダメだけど、チームによってどちらかに "寄せる" ことは効果的で、その際の判断基準も書かれている。ジュニアが多かったらコントロールしてあげる必要があるとか。

チームが大きくなりすぎているときの警告サインは「プロセスロス」「多元的無知」「責任の分散」
とはいえ大きいとき起きやすいというだけで、大きさが大きすぎないときでもなくこれが起きてしまう場合もあると思う。
自分がフロントエンドチームをリードするときのことを考えると、

  • プロセスロス対策:作業箇所や意図がコンフリクトしないようなタスクを各メンバーに割り振る
  • 多元的無知対策:決定に対して常に各メンバーに意見を求め続ける、心理的安全性を確保する
  • 責任の分散対策:互いに今どういう意図でどういう作業をしているのか把握できている状態を作る

とかかなー
逆にこのへんをやれたら安定してスケールできるチームになるのかも。

22.5 チェックリスト

コードの完成のチェックにはチェックリストよりCIのほうがいいな…PRテンプレにチェックリスト入ってるパターンとかあるけど、だいたい形骸化していくので。。
テストでは有益だと思う。ユニットテストからQAチームでの手動テストまで。というかテストするためには仕様の段階で考慮・定義されてる必要があるので、開発に閉じたところに置くんじゃなくてプロダクトチーム全体で共有・更新していけるフォーマットになっているのが重要だなと感じる。
リリースでは、有益なんだけど、順番に依存するものが多くなりがちな気がする…

手順はチェックリストに含めるべきではない

っていうのはチェックリストに関するひとつ大きなナレッジだなと思ったけど、リリースのチェックリストってだいたい手順書がチェックリスト形式になったものだったりしない?むずかしい。。

22.6 ガイダンスの提供

これはかなり参考になる。たとえば新規ライブラリの採用について、アーキテクトは以下のようなガイダンスを提供できる。(※カッコ内は私が当てはめた例)

特別な目的のもの(react-pdfとか):開発者の承認で入れられる
汎用的な目的のもの(react-useとか):アーキテクトの承認で入れられる
フレームワーク(Reactとか):アーキテクトの決定による

これはこのまま今のプロジェクトにも応用できるなと思った。
あとは既に導入済みのライブラリと重複がないかチェックしてから提案するとか…

つまり、具体的にあのライブラリはOKでこれはダメとかではなく、現場が自律的に動けるような大枠のルールだけ決めておくってことだよね。こういうのもちゃんと言語化して明文化しておけるといいなと思った。

コラムのScala好きな人とのエピソードは、ちょっとスカッとジャパン的な印象を受けてしまったw過去の経験らしいけどこんなに劇的に変わることある?まあでもビジネスインパクトを考える概念がまったくない人にはその物差しを提示するだけで劇的なことだってことなんだろうな…


章冒頭の引用だけど、

卓越したソフトウェアアーキテクトと他のソフトウェアアーキテクトの違いの1つは、チームの生産性を高められるかどうかだ。

これはほんとそう思う。というか、いち開発者もそうだし、全職種において言えることだと思う。

各職種のハードスキルがあるかどうかと、常に組織やチームのことを考えられるかっていうのは独立しているので、どっちかを見ればもう片方がわかるものではない。
そして出来る人、スペシャリストと働きたいって考えると前者のスキルが飛び抜けてある人を欲してしまうんだけど、実際チーム開発していくと、ひとりのハードスキルの高さによるアウトプットよりも、コミュニケーションや協調の重要性をわかっている人同士がフォローし合いながらプロジェクトを進めていけることによるアウトプットのほうが長期的に見て上回ることが多いんだよな。それは個人に依存しないチームの力ということでもあるし。
もちろん両方必要なんだけど、両方ある人って超まれ。なのでどっちかが7, どっちかが9ってなったとき、昔は前者9後者7の人と働きたかったけど、今は前者7後者9の人と働きたいなと思ってる。 今所属している会社の採用基準にも通づるところがある。実際そういう採用ができているのでチームとしての力が最大限に発揮できているんだと思う。
だからこの本でソフトスキルが重視されているのも頷ける。経験が長い人ほどそこの重要性を実感している割合が高くなる傾向があると思う。

23章 交渉とリーダーシップのスキル

23.1 交渉とファシリテーション

"効果的なソフトウェアアーキテクトは、すべてのステークホルダーが納得するソリューションを作り出せる。" これはプロダクトマネジメントにも重なるな。

ビジネスステークホルダーでの交渉では語法やバズワードを上手に使おうっていうところはちょっとうけた。でもバズワードって実際ほんと効果的。響きで穿って見ずに「その人の関心を突く」と考えれば正攻法なんだよな。
交渉の際は相手の関心事を見抜くのがまず最初の第一歩。
あと、コストや時間を根拠にするのは正しいけど、まずそこから入っちゃうと交渉がうまくいかなくなるから(正論で殴ることになるから?)、それは最後の手段としてとっておく(他の正当性を先に探す)、というのはなるほどだった。

他のアーキテクトとの交渉や開発者との交渉のところは、自分のこれまでの経験にも重なるところが結構ある…
なんでこういう設計にしてるの?こういうほうがよくない?という議論は常にありうるし、あって然るべきだけど、そればかりしてるのも不健全なので、うまくファシリテーションできる必要がある。

「こうしなくてはならない」というメッセージではなくて、Whyとルールを事実として伝える。その上で課題に一緒に向き合う。
あとは問題提起者に解決策を見つけてもらうというのも本当そうだな。これはやりすぎると問題提起しづらくなる雰囲気を作っちゃうので塩梅だけど、具体的な選択肢の間で対立したり、気持ちの強い要望とかにはいい方法だと思う。
このあたりはまじで実践したい。

23.2 リーダーとしてのソフトウェアアーキテクト

私達は、効果的なソフトウェアアーキテクトであることの約50%は、優れたピープルスキル、ファシリテーションスキル、そしてリーダーシップスキルを持っていることだと考えている。

まじか。イントロダクションでぐぬぬ〜ってなってたけどやっぱそうだよね。。

「プラグマティックでありながらもビジョナリーであること」

ビジョナリー=想像力や知恵を持って未来を考える
プラグマティック=実践に基づき現実的である

ビジョンと現実のバランス。すごいCTOっぽい。

アーキテクトとして敬意を得るには、プラグマティックとビジョナリーのバランスを保つことが大切だ。ビジネスステークホルダーは一連の制約に収まりつつもソリューションにビジョンがあることを評価し、開発者は実装者として(理論的ではなく)プラグマティックなソリューションであることを評価する。

やっぱり上の方のレイヤーを担当するに従って、現実的であるだけではダメで、ビジョナリーであることも求められる。それはアウトプットの質に寄与するところでもあるけど、そもそも同じ/近いレイヤーにいる人との共通言語でもあって、その人達から信頼を得るためにも必要ということなんだろうな。

ビジョナリーであるとは、問題に対して戦略的思考を適用するということであり、それはまさにアーキテクトがすべきことでもある。

戦略的思考は本当に日々のコーディングとかとは全然違う考え方というか、ボトムアップではなくトップダウンの思考ってかなり考え方を切り替えないと難しい。
今の会社に入ってはじめてキックオフとかで要求されるようになったスキル。
でもメンバーでもこの思考があると上のレイヤーの人の思考や言葉の背景がわかるようになるし、自分としても見える世界が広がるから今メンバーでありながらそこに取り組めてることはとても貴重だなと感じる。それをここ読みながら改めて思った。

23.2.3 手本を示してチームをリードする

敬意を得てチームをリードするには、基本的なピープルスキルが必要だ。

繰り返しだけど本当そうですね…

開発者とアーキテクトの議論の例、参考になる。これはテックリードも気をつけないといけないやつ。
正解が見えている場合でも「〜すればいい」と自分の意見を押し付けるのではなくて、「〜は検討してみた?」「〜はどう?」と質問の形にすることで、一緒にソリューションを考えているというような協調的な会話が生まれる。
ここに表れているように、語法の使い方がとても重要。(語法ってあんま聞かないけど、表現とか言い方として捉えてる)
チームメンバーに対して語法の使い方も指導することでチームメンバー間での敬意やコラボレーションも醸成出来ると。人間力が高い…

あとは、会話や交渉の際に相手の名前を呼ぶとか、要求を頼み事に変えるとか、効果的な握手(これは日本では無いな…)とか、ビジネス書に書かれてそうなテクニックも紹介されている。これがここに書かれているということは実際に大事であり効果的であったってことだろう。実際自分も "一見どう見えようとも、それはつねに人の問題" であることを痛感しているから、これらのテクニックを全然陳腐だとは思わない。むしろ使いこなせていけたほうが良いチームメンバーになれるんだよなぁと思う。

23.3 開発チームに溶け込む

でたミーティング多すぎ問題!!😂 どの国でも一緒なんだな…
実際役割が増えれば増えるほど会議は増えていく。今自分も結構困ってる。

  • 情報共有の場であれば参加せずに議事録を読む
  • 議論の場であれば事前にアジェンダを見て参加を判断する

このふたつはそうだな。
なんか、どこかで何かしら決定されたことに異議があっても場に参加していない人が後から言うのってあんま微妙だなと思っていて、その状況を防ぐために色々参加してしまいがちなところがある。
でもこのふたつならそのリスクを最小限にして会議時間を減らせそう。実践してみよう。

24章 キャリアパスを開く

朝、仕事前の20分ルールでキャッチアップの時間をとる。
新しい情報や技術をどうキャッチアップし続けていくかはソフトウェアエンジニアがずっと付き合い続ける課題だよなー。しかも家庭とかできると投下できる時間はどんどん減っていく…
20分、かつ「よく知らない言葉を概要ぐらいはわかる言葉にする」もしくは「もう少し掘り下げて知識を得る」という具体的な目的があるのがいいなと思った。

私は情報得るのRSSかTwitterだから、わりと昼休みとかに休憩がてら読んじゃいがちなんだけど、頭休まらないし時間足りないしってなっちゃうんだよな。朝PCの前でっていうのはエンジン始動にもなってよさそう。

テクノロジーレーダー、見たことある! 社内で紹介してくれたメンバーがいた。
技術全体の話だからフロントの局所的なことは載ってこないだろうな、これのフロント版とか独自に作れたらいいのかも(書籍内でも自分版を作ってみるといいって書いてた)、とか思ってたら、 v23ではSWRとかRecoilとか載っていたらしい、まじか!!
今は載ってないけどページはあった。SWR、去年Trialまでいってた。

https://www.thoughtworks.com/radar/languages-and-frameworks/swr

2020年時点でもAssessだったので、結構攻めの選択だった時期から載ってたんだな。これ見て、技術選定するとき常に参照するとよさそうだなと思った。大きくスタイルが変わるような有益な選択肢は、いちライブラリであっても載るんだな。私の2020年時点での技術選定 も、内容は結果的にはまさにレーダーのAssessに沿ってたけど、こういうデータも根拠にできたりするといいんだろうな。

SNS使おうねとかもあった。このへんはわりとやれてる。技術者として信頼できるアカウントがつぶやく記事とか追ってるだけでだいぶキャッチアップになる。

自分のキャリアと照らしあわせて

(1章の感想で「それについての深堀りはここに書くと長くなりすぎるので別で書きます。」って書いたこと。超ひとりごとなので、発信の気持ちではなく独白として残す)

ちょうどここ最近、キャリアの面で答えが出せなかった問題があって。

上のセクションでも引用した 「一見どう見えようとも、それはつねに人の問題」 っていうのは、キャリアを重ねるにつれてすごく身に沁みてきていた。「結局人なのかも?」みたいな気持ちは、この本を読む前から自分の中に生まれ始めていた。

ただ自分は、人との関わりが苦手…というか、人との関わりに脆弱。仕事仲間は好きだし、コミュニケーションはまあまあうまくできるほうなんだけど、裏側で色々考えすぎて人の3倍ぐらいMP消費してる気がするしめっちゃ悩むし単純にしんどい、っていう特性がある。
この特性のせいで、ピープルマネージャーとかプロジェクトマネジメントのほうに踏み出す気持ちになれない。いろいろ気を回しすぎて擦り切れて病みそうなのが目に見えてるから。

だから「結局人なのかも?」を感じ始めているのに、自分ではその課題を解決できない、したくないというジレンマがあった。

そんなジレンマを抱いているときに、(※会社からのメッセージではなく、全然別の文脈での世論として)「ハイパフォーマーなプレイヤーよりも複数人を束ねられるマネージャーのほうが組織への寄与(事業への価値)が大きい」みたいな言説が耳に入って、なかなか刺さっちゃったんだよね。自分でも薄々「結局人」を感じ始めていただけに。もっと若い時だったら「んなことないだろ」って流せたんだけど、もう実感しちゃってるから流せなくて。
しかも私はそもそもソフトウェアエンジニアとして突き抜けたハイパフォーマーなタイプでもなくて、平均よりは2段階ぐらい良い、ぐらいの自己認識。
平均より得意 + 人との摩擦から逃げたい + 技術が好き っていうのの総合でテックリードやっているような実感がある。だからその言説を跳ね返せるほどのx10, x100ぐらいの突き抜けたパフォーマンスを技術力で出してやるぜ!っていう思考にもなれない。

それで反骨精神で「自分ぐらいの技術力でも、技術的なアプローチで組織マネジメントと同じぐらいの価値を出すことはできないのか?」っていうのを考えていたんだけど、そこに答えが出せなくて、ぐぬぬとなってた。答え出せないってことは、技術ちょい得意ぐらいの凡人が価値出したいならやっぱ人のマネジメントなのかな?みたいな感じで若干キャリア迷子になってた。

でもこの本読んでそこへの答えを見つけられた。
この本から「ソフトウェアアーキテクトも結局人との関わりだから "結局人" であって、それを解決できるだけのソフトスキルが要るよ」っていうのを明確に突きつけられて、あ、なんだ、結局組織リードも技術リードも対峙する課題は一緒なんじゃん、 "結局人" と向き合っているんじゃん、ってことは同じ価値があるんじゃん、っていう結論に至れた。

技術の道を選ぼうが結局人からは逃げられないんじゃんっていう絶望もあったけど、逃げたいのは難しいからで、人間にとって人間の難しさは普遍的なもので、それを解決するから価値なんだよね。
技術的なリードをする上でも技術力だけあればいいってことはなく、人と対話して交渉してひとつになって問題を解決していくということは変わらない。
組織/技術問わず「結局人」だから、それを解決できる人間は少ないし、だからこそ間違いなく価値を生んでいる、というロジックが自分の中に立ったのが良かった。

だから腹も括れた感じがする。
今までは「技術と向き合いたいのに何で人との関わり方を考えないといけないんだろう」って思うときもあったけど、これからは「すべての問題は結局人であって、それを技術リードという立場から解決していく」という思考になれた。これから自分のチームがスケールしていくにあたって今必要な気付きだったと思う。

という背景からのこのツイートだったんだけど、140字で表すには余白が少なすぎた…

https://twitter.com/yoshiko_pg/status/1517721982602661889

アクションしてみたいことリスト

  • 設計について考えるとき「構造」「アプリケーション特性」「アプリケーション決定」「設計指針」に分解して考える
  • 設計について考えるとき、統制の方法についてもあわせて考える
  • 設計について記すとき、少なくとも「なぜ」を残す
    • 本当はADRの形で残せるのが一番良い
  • メリットしかない選択肢は無いので、トレードオフを見つける
  • 凝集度とコナーセンスの尺度について覚える
  • 計測する
    • 実際のアプリケーション動作時のパフォーマンス計測
    • 循環的複雑度の計測(eslint/complexity でできそう)
    • テストカバレッジの計測
  • 設計するとき、ビジョンと現実性の両方が必要であることを思い出す
  • 設計だけでなくガイダンスを提供する
  • 設計について議論する際
    • Whyとルールを事実として伝える
    • 問題提起者に解決策を見つけてもらう
    • Howの提案は質問の形をとる
  • コントロールと放任どちらにどれぐらい寄るべきなのか、チームごとに考える
  • ミーティングについて
    • 情報共有の場であれば参加せずに議事録を読む
    • 議論の場であれば事前にアジェンダを見て参加を判断する
  • 仕事前の20分ルール
このスクラップは5ヶ月前にクローズされました
作成者以外のコメントは許可されていません