$shibayu36->blog;

クラスター株式会社のソフトウェアエンジニアです。エンジニアリングや読書などについて書いています。

進化的アーキテクチャ読んだ

最近アーキテクチャ関連の知識を身につけようと思い、進化的アーキテクチャを読んだ。

言葉の定義が独特で、正直この本は難しいな〜と思った。勉強になったなと思うことは、変更しやすいアーキテクチャを作るための流れの部分。自分は以下のように作ると解釈した。

  • そのアーキテクチャが対象とする領域で、進化しても保護したい重要な特性を特定する
    • 例: スケーラビリティ、監査可能性、即応性など
  • それぞれの特性に対して適応度関数を定義する
    • 適応度関数とは、あるアーキテクチャ特性がどの程度満たされているかを評価する客観的な指標
    • たとえば即応性を、全レスポンスの95%tileのmsで指標化するみたいなイメージ
  • 定量指標がどの値を超えたら望ましくないかを定義し、開発フローに組み込む
    • たとえば全レスポンスの95%tileを500ms以内にする、平均1sを超えるエンドポイントを作ってはならないなど
    • 指標化したら、自動で計測できるようにしたり、継続的に観察できる場所に置いておいたりする。それにより変更があったとしても重要な特性が守られ続けていることを確認する

あとは以下の文章が刺さったかな。気をつけたい。

ほとんどの開発者は有用なものを作るためにフレームワークを使うよりも、フレームワークを作る方を好む。メタ作業はただの作業よりも面白いから。楽しいメタ作業であるという理由だけでアーキテクチャを構築してはならない

読書ノート

- ソフトウェアアーキテクチャづくりには、要件だけでなく、パフォーマンスや監査可能性などのあらゆる関心ごとが釣り合う解決策を探らなければならない 265
    - 関心ごとは、システムを構築する際の「何を」や「どうやって」といった判断をひっくり返す可能性があるもの
- アーキテクチャ作りの関心ごとに、進化可能性を付け加えたいということが本書で言いたいこと 282
- 昔はソフトウェアの変更が高価だったためアーキテクチャは変えにくいものと定義されたが、DevOpsなどの開発プラクティスの進歩によって、その前提を無効化した。一方変更が難しいという立場を取るならば今でも変更が難しくなってしまう。変更しやすさをアーキテクチャの基盤原理に組み込めれば、変更はもはや困難でない 387
- 進化的アーキテクチャの定義:進化的アーキテクチャとは、複数の次元にわたる漸進的で誘導的な変更を支援するものである 418
- 適応度関数を使い、アーキテクチャとエコシステムが時間と共に進化していく中でも、重要な特性を保護する 505
    - 気づき:パフォーマンス目標はSLOによって保護されているみたいなものが適応度関数の事例になりそう
- 適応度関数とは、あるアーキテクチャ特性がどの程度満たされているかを評価する客観的な指標 656 ☆
- 適応度関数は、3つの単純なカテゴリに分類できる 846
    - 主要なもの:技術や設計を選択する上で重要なもの。これらの要素を中心とした変更を容易に行えるようにする設計上の選択を探ることに、より多くの労力をさかなくてはならない。例えば、銀行アプリケーションなら、パフォーマンスと回復力が主要な次元となる
    - 関連性のあるもの:機能レベルで考慮する必要があるものだが、アーキテクチャ上の選択を誘導することはない。例えば、コードベースの品質に関するコードメトリクスは重要だが、主要な次元ではない
    - 関連性のないもの:設計と技術の選択に影響を与えないもの
    - 気づき:適応度関数がどれに所属するかは対応する事業ドメインによって異なる
    - 主要な適応度関数と関連性のある適応度関数を適応した結果は、共有スペースなどで可視化し続ける必要がある。それによりその知識を保ち続けられる ☆
- 漸進的な変更 950
    - 気づき:この辺は「モノリスからマイクロサービスへ」の方がわかりやすい
- 進化的アーキテクチャ構築の流れ 2494
    - 進化しても保護したい次元を特定する
        - 〜性のリストを参照 282
    - それぞれの次元に対して適応度関数を定義する
        - 気づき:つまり定量指標を定義するということ
    - 定量指標がどの値を超えたら望ましくないかを定義し、デプロイメントパイプラインに組み込む
- ほとんどの開発者は有用なものを作るためにフレームワークを使うよりも、フレームワークを作る方を好む。メタ作業はただの作業よりも面白いから。楽しいメタ作業であるという理由だけでアーキテクチャを構築してはならない 2642 ☆

git logの内容を検索する-Sと-Gの違い

ずっとgit logの内容を検索するときに-Sオプションを使っていたが、実は近いオプションに-Gオプションもあり、探したい内容によっては使い分けないとダメということを初めて知った...

詳しくはhttps://git-scm.com/docs/git-log-S-Gのドキュメントを見てほしい。簡単にまとめると

  • -Sは指定した文字列の出現回数が変わるdiffがあるcommitを検索する
  • -Gは指定した正規表現がマッチする文字列がdiffにあるcommitを検索する

ドキュメントの事例部分が結構わかりやすくて、以下のようなdiffがあった場合

+    return frotz(nitfol, two->ptr, 1, 0);
...
-    hit = frotz(nitfol, mf2.ptr, 1, 0);
  • -S frotzで検索をかけると、frontsの出現回数は変わってないのでマッチしない
  • -G frotzで検索をかけると、diffの中にfrotzという文字列は存在するのでマッチする

この差を意識しないと意図したcommitを探すことが出来ない。使い分けよう。

特定ファイルを更新したマージコミットを探す

あるファイルが最近どの程度の頻度で更新されたのか、マージコミット単位(≒PullRequest単位)で調べたいことがあった。git logのコマンドを使ったら簡単に調べられたのでメモ。

たとえば1年以内に https://github.com/x-motemen/ghq のレポジトリで .github/ 以下に変更を加えたマージコミットを取得したい場合はこんな感じ。

$ git log --merges -m --first-parent --pretty=format:"%cd - %an: %s(%H)" --since="1 year ago" .github/
Sun Apr 16 23:27:26 2023 +0900 - Masayuki Matsuki: Merge pull request #359 from x-motemen/coverage(e7f736f22376d3e897464a1ef5425fb8d3a11b7c)
Thu Feb 23 00:45:12 2023 +0900 - Masayuki Matsuki: Merge pull request #362 from x-motemen/version-file(a93dc0900f4839ecff9af2fabc3bcc5dc7d4771e)
Wed Feb 22 20:47:05 2023 +0900 - Masayuki Matsuki: Merge pull request #358 from x-motemen/fix-win-test(c6bf0744d27d79328fcf608187bf9573e5f87a3d)
Wed Feb 22 16:45:41 2023 +0900 - Masayuki Matsuki: Merge pull request #356 from hezhizhen/typos-lint(434061b60df2bf2b5acccc70d5cf620f1587b029)
Wed Feb 22 11:22:17 2023 +0900 - Masayuki Matsuki: Merge pull request #354 from x-motemen/tagpr-from-v1.3.0(d398714567c147122649f81d2a4f7ed08e477e9d)
Wed Feb 22 10:55:24 2023 +0900 - Masayuki Matsuki: Merge pull request #353 from x-motemen/tagpr(367183b5c20512c5cb09b4766d8b0b269e7b7e35)

それぞれのオプションの意味を解説すると

  • --mergesでマージコミットだけに限定
  • -mを付けると、gitのコマンドがマージコミットのdiffを認識できるようになる
    • これがないとどのファイルを変更したのかなどの情報が取れない
  • --first-parentを付けると、トピックブランチが変更した差分のみを見れる
    • main...topic-branch的な差分になるので、あるマージコミットが実際に変更した差分になりやすい
  • --prettyはフォーマットを決めている
  • --sinceで1年以内に限定

これにさらに-pオプションを付けるとdiffを見ることができ、また-Sや-Gを使うことで検索もできる。

$ git log -p -G go-version-file --first-parent -m --pretty=format:"%cd - %an: %s(%H)" --merges --since="1 year ago" .github/
Thu Feb 23 00:45:12 2023 +0900 - Masayuki Matsuki: Merge pull request #362 from x-motemen/version-file(a93dc0900f4839ecff9af2fabc3bcc5dc7d4771e)
diff --git a/.github/actions/release/action.yml b/.github/actions/release/action.yml
index da9fe61..ea39403 100644
--- a/.github/actions/release/action.yml
+++ b/.github/actions/release/action.yml
@@ -13,7 +13,7 @@ runs:
   - name: setup go
     uses: actions/setup-go@v3
     with:
-      go-version: 1.x
+      go-version-file: go.mod
   - name: release
     run: |
       make crossbuild upload
...