📘

ソフトウェアアーキテクチャの基礎 ―エンジニアリングに基づく体系的アプローチ を読んで感じたことまとめ

2022/06/21に公開

アーキテクチャとは、と聞かれて、なんとなく答えれるけど、全体像が分かってなかったので、この本読んで気づいたり心に残った点をメモ

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

最初に全体の感想

ボリューム多いが、一度全部ざっと読んでおくと、いつかまた見返して使えそう。
また、いろんなアーキテクチャの経験を積んだ後、読み返して深まる知識もありそうだし、
ここから、さらにどこかの分野を深める(例えばチームの効率を上げる方法とか)きっかけにもなるなと感じました。

少しでもアーキテクチャという言葉に興味ある人は手にとって損は無いかと。

アーキテクチャの指す範囲

時代に合わせてアーキテクチャに求められる範囲は広がっており、明確な定義はない。
開発チームをリードする対人スキルや、アーキテクトが下す多くの決定に対して社内で承認得るための政治力も必要。

アーキテクチャ特性(イリティ、ility)

可用性、継続性、パフォーマンス、弾力性、などで、定義は曖昧で差す範囲、用語もそれぞれ

最善なアーキテクチャはなく、むしろ最悪でないアーキテクチャを目指すべき。多くの決定はトレードオフでしかないから。またアーキテクチャはイテレーティブが良い。変更容易な状態を作っておく。

設計方針も同じで、AかBか決めれないときは、変更容易性を判断基準として加えて良さそう

アーキテクチャ特性は、ドメインの関心事(要件)から考える。明示的なものと暗黙的なもの両方ある。
暗黙的なものの例としては

  • 可用性:ユーザが確実にアクセスできる
  • 信頼性:ユーザが利用している間、サイトが稼働し続ける
  • セキュリティ:いわずもがな
暗黙的なものを見積もる際に明示化することが大事そう

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

アーキテクチャの最上位分割、の例に、レイヤードアーキテクチャがある。プレゼンテーション、ビジネスルール、サービス、永続化。バリエーションの一つがMVC。またこのアーキが組織に影響する(コンウェイの法則)

フロントエンドエンジニア
バックエンドエンジニア
のようなチームは、このレイヤードアーキに沿った組織設計と言えるのか!なるほどー

ドメインによる分割だと、
逆コンウェイ戦略で、職能横断チームを編成しやすい
一方、特定の処理を行うコードが複数の箇所に現れる

コンポーネント設計

  • アクター/アクションアプローチ
    • 最近これよく意識する。ウォーターフォール開発と相性がいいらしい(ほんとに?
  • イベントストーミング
    • DDDの影響、DDD(マイクロサービスなど)と相性良いらしい
    • コンポーネント間のメッセージやイベントからコンポーネントを洗い出すイメージ
  • ワークフローアプローチ
    • ロールのワークフローを洗い出す

同じ機能でも、アーキ特性が異なる場合は、コンポーネントを分離したほうがいい場合がある

アーキテクチャ

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

代表的なのは、プレゼン、ビジネス、永続化、データベース。永続化がビジネスに含まれる3層もある。
レイヤー間のアクセスを制限している閉鎖レイヤーと、制限のない開放レイヤーがある。
ビジネス層の共通コンポーネントをあつめたサービスレイヤーを新規で作り、開放レイヤーとするパターンがある

レイヤードアーキテクチャで気をつけること

アーキテクチャシンクホールパターン

シンクホールの割合が多くなってないか。
例えば全リクエストの80%あれば、レイヤードアーキテクチャが適切でないことを示す良い指標になる。
シンクホール:各レイヤーをスルーするだけの処理。不必要なオブジェクトのインスタンス化と処理だけ行われてメモリ消費とパフォーマンスに影響。

アプリケーションの大きさ

アプリが小さい、または、予算や時間に厳しい制約があるときの出発点としてレイヤードアーキはいい選択肢となる。
が、アプリが大きくなってくると以下に悪影響がでる
保守性、アジリティ、テスト容易性、デプロイ容易性

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

シェルスクリプトと馴染みのあるアーキ
プロデューサー、テスター、トランスフォーマー、コンシューマー、からなる
Apache Kafka など

データ分析における、データレイク、データウェアハウス、データマートの流れや、IoTのセンサー値の受け取りから精査、集約、保存、が、このアーキに当てはまりそう 

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

コアシステムとプラグインコンポーネントからなる。例 Eclipse IDE

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

荒い粒度のサービスと、モノリシックなデータベースから構成。例えば、5,6個のサービスと、1,2個のDB

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

ブローカー:高分散、各コンポーネントは受け取ったら投げるだけ
メディエーター:処理のステップを把握し管理(中央管理っぽい)

AWS Step Functions はまさにこれか。 

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

データベースのデータをアプリのメモリ内にコピーし、アプリをメモリ内データを参照
更新情報は、非同期でDBと通信。DB参照しメモリ内データ更新も非同期。
データベース接続のボトルネックを解消

アプリ内キャッシュは、
アプリごとに同じキャッシュをもつレプリケーションキャッシュと、中央管理する分散キャッシュの選択肢がある
どちらを選ぶかは、パフォーマンス or 一貫性、キャッシュサイズが100MB以下 or 500MB以上、更新頻度が低いか高いか、対障害生が高いか低いか

ニアキャッシュ
レプリケーションキャッシュと分散キャッシュの組み合わせ

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

DDDに大きく影響
サービスベースアーキテクチャとは異なり、サービスごとにDBを持つ

マイクロサービスだー、と思って設計したら実はDB一つでした、であれば、
これは、サービスベースアーキテクチャと言えそう

フロントエンドも分割するのが理想だが、現実は実用性や制約により、一般に以下の2パターンある

  • モノリシックUIパターン
  • マイクロフロントエンド
    • フロントエンド内の各マイクロコンポーネントがそれぞれのサービスを利用

サービス境界を超えてトランザクションが必要となる場合、サービス粒度を見直すきっかけ。(トランザクションが不要になるよう粒度を大きくすることを検討)
例外として、あるサービスが複数サービスの呼び出しのメディエーターとして振る舞いトランザクションを調整するサーガパターンもあるが、複雑になるので使用は控えめに

アーキテクチャの決定時のアンチパターンにはまらないために

  • 決定までの期限を決める
  • 分析を深くしすぎない
  • 開発者と協力する
  • 決定の根拠はドキュメントに残し、関心のある人に伝えると効果的

ADR (Architecture Decision Record)

ステータス管理して、破棄ステータスとそれに変わって決定したADRを紐付づける
ADRの自己承認の可否基準:コスト、チーム間の影響、セキュリティ、がおすすめ。これらの中である基準を超えたら上位の機関に承認を求めるというルール設定しておく。

大抵、破棄した側の情報が残らず、最終決定したものしか残ってない。
ADR,version 管理もあったほうが良さそうなので、issueよりrepogitory 管理か。
と思ったが、wikiか共有ファイルサーバがおすすめ、とのこと。
変更履歴もひと目で分かる状態が良さそう。

アーキテクチャ上のリスク分析

リスクストーミング、やってみたい。
アーキ図見ながらみんなでリスクの洗い出し(特定)して合意、軽減する

プレゼンテーション

プレゼンテーションとインフォデッキ(情報全部載せ)は似てるが異なる。インフォデッキはメールで送って見てもらえばいい
プレゼンテーションは、資料と話者の2チャンネルある

効率的なチームにする

詳細なコントロールしても(コントロールフリーク)緩すぎても(アームチェアアーキテクト)よくない
コンポーネントの境界までは決めるが、中身の設計は開発者に任せる
チームの状況(サバイバルフェーズ、学習フェーズ、自己組織化フェーズ)に応じてコントロール程度を変える(エラスティックリーダシップ)

コントロール度合いを決める5つの指標

  • チームの親しみ具合
  • チームのサイズ(人数)
    • 4は少なく12は多い
  • 全体的な経験
  • プロジェクトの複雑さ
  • プロジェクトの期間
    • 2ヶ月は少なく2年は長い

チームの警告サイン

  • プロセスロス: グループの潜在能力ー実際の生産性
  • 多元的無知: 自分一人が否定意見があっても黙ってしまう
  • 責任の分散: 誰かが助けると思って誰も助けない

チェックリストの活用

おすすめが

  • コード完成
  • ユニットテスト、機能テストのケース例
  • リリース

ライブラリの利用時の質問

既存システム内に重複機能がないか
どんな根拠で利用提案しているか
特にビジネス上の根拠を考えてもらう

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

ビジネスステークホルダーとの交渉

コストや時間の観点での交渉は最後に取っておくのがおすすめ(これは意外)もっと重要な他の正当性や合理的な理由を先に試すべき

例えば分割統治を使って過剰な要求のスコープを限定する。(たとえばファイブナインの可用性を求められた際に特定領域に用件を限定する

開発者との交渉

  • プラグマティックでありビジョナリーでもある
    • ビジョンを示しつつも現実的な解にも落とす
  • 手本を示してチームをリードする
    • 深く理解せずとも、全くわからん部分は無いようにしないとな
  • 単なるコミュニケーションではなく、コラボレーションする
    • 自身の判断を押し付けない
  • 会話や交渉の中で相手の名前を頻繁に呼ぶようにする
    • 細かいテクニックやと思うけど理解できる

開発チームの溶け込む

  • 会議は減らす努力する
    • 事前のアジェンダ確認で、自分が必要か確認
  • 開発者のフロー(集中状態)の邪魔をしない
  • チームと一緒に座る
    • 特別な椅子に座らない

テクノロジーレーダー

既存技術と新興技術のリスクとリターンを評価するための常に更新され続ける生きたドキュメント
レーダーにある4つのリング

  • 取り扱い注意(Hold)
    • 話題だが未実証、新しすぎる、など
  • 評価(Assess)
    • 調査する価値がある
  • トライアル(Trial)
    • 取り組む価値がある
  • 採用(Adopt)
    • 業界が採用すべきと強く感じている

Discussion