知っておきたい最近の(?)エンジニア組織醸成単語など

## この記事は
チームの若手向けに10分LTで紹介した内容の備忘録。
単語を知ってもらいたかっただけなのでかなりざっくりした説明。
適応度関数は個人的に好きなので「エンジニア組織醸成」なのか不明だがとりあえず混ぜ込んだ。（そもそも「エンジニア組織醸成」ってなんだろう。）

## FourKeys

主に開発生産性を分析するための4つのメトリクスの総称。
[DORA (DevOps Research and Assessment)](https://dora.dev/)が提唱したらしい。

### メトリクス内容
4つのメトリクスは、「開発生産性を測る指標」が二つと「サービスの安定性を測る指標」の二つで定義されている。

  - 開発生産性を測る指標
    - デプロイの頻度
      - パイプラインを通って時間経過においてどれほどデプロイが実行されたかを示す
    - 変更のリードタイム
        - 完成したコードや設定変更が、パイプラインを通ってデプロイされるまでにかかる時間
  - サービスの安定性を測る指標
      - 変更時の障害率
          - デプロイされた変更のうち、サービスに障害を引き起こした割合
      - サービス復旧時間
          - サービスに障害が発生してから、その障害に気づき修正されるまでの時間
### メトリクスの利用の仕方
- 作業のメトリクスなので、値をハックしようと思えばいくらでもハック可能
    - 極論、毎日何もなくても強制デプロイし続けるとか、観測の時間の定義を変えるとか
    - それでは意味がないので、あくまで現状の組織の課題を発見する手法として利用すべき
- 開発者（チーム全体）でこの数値を意識し、数値の原因を探ったり健全な改善のために何をすべきかを議論するのが理想

## コンウェイの法則
  - 「システムを開発する組織は、必ずその組織構造に倣ったシステムが構築される」という法則
  - 超簡単にいうと
    - BEチームが何しているかわからないFEチームが、実はBEですでに計算済みの値をFEで再計算していた
    - 仲のいいチーム間は最適な連携でシステムを構成できるが、距離感のある組織とでは不都合が多いIFのやり取りになる
    - など
  - 詳しくは[なぜ、組織のつくりとソフトウェアアーキテクチャは似てしまうのか](https://qiita.com/hirokidaichi/items/d12fcce80ee593bcf34d)を読むといい

## チームトポロジー
  - 概要
    - 組織感の距離があるなどの場合、コンウェイの法則によって開発業務の中でもかなり不要なオーバーヘッドが発生してしまうため、それを避けるチームづくりを行う手法
    - コンウェイの法則を逆手に取った逆コンウェイ戦略という組織づくりの手法を、より効果的に実践する方法論
  - チーム構成
    - ストリームアラインドチーム
      - ドメインに責務をもち、安定したフィーチャーデリバリーを行うチーム
    - イネーブリングチーム
      - ストリームアラウンドチームを横断的に支援する 
      - 特定のテクニカルドメインに関する支援を行う
    - コンプリケイテッド・サブシステムチーム
      - 複雑なサブシステムについてストリームアラインドチームの認知負荷を下げるチーム
    - プラットフォームチーム
      - ストリームアラインドチームが自立的に仕事ができるようにプラットフォームを提供するチーム
      - サービステンプレート
  - チームインタラクションモード
    - コラボレーションモード
      - 他のチームと密接に協力して作業すること
      - 密な連携により高い効果を期待できる反面、コラボレーションに大きな負担がかかる
    - ファシリテーションモード
      - 障害を取り除くために他のチームを支援したり、支援を受けたりすること（コラボレーションとは異なり指導者が明確）
      - 明確な効果を期待できる反面、効果の高いファシリテーションを行える人材が必要
    - X-as-a-Serviceモード
      - IFを通じたやり取りを行い、最小限ののコストで連携すること
      - チーム間の認知負荷が低い反面、提供側が正しいIF(サービス)を提供できない場合、ボトルネックになる可能性もある
  - ストリームアラインドと各チームとのインタラクションモードの理想的なメトリクスは以下

|             | ストリームアラインド |  イネーブリング   | コンプリケイテッド・サブシステムチーム | プラットフォーム |
|:-----------:|:----------:|:----------:|:-------------------:|:---:|
| チームインタラクション | コラボレーション/ファシリテーション  | 　ファシリテーション |   X-as-a-Service    | X-as-a-Service  |


## 適応度関数(Fitness Function)
「[進化的アーキテクチャ](https://www.oreilly.co.jp/books/9784873118567/)」が初出の「アーキテクチャ特性がどれほど満たされているか」を測定する指標。
ソフトウェアに様々な機能改修・インフラ変更などを加えていく中で、クラスベースのロジックをテストするテストコード(ユニットテスト)やアプリケーションとしての挙動を担保するのアプリケーションのテスト(インテグレーションテスト)だけでは、アーキテクチャの特性が満たされていることを継続的に測るには不十分。
パフォーマンスやセキュリティなど、様々な品質特性を（可能であれば）自動で継続的に担保していく仕組みを構築することが望ましい。それを実現するために実装されるテスト。
テストといってもテストコードだけではなく、メトリクスの監視から通知されるアラートや負荷テストツールの実行結果の通知、CI上で脆弱性を通知するSaaSの利用など、手法は様々。

### 関数の区分
適応度関数を実装する上で、関数の役割の明確化の観点から、以下の区分を意識して関数を定義することが望ましい。

- 規模
    - アトミック/ホリスティック
- 実行契機
    - トリガー式/継続的/手動
- 実行場所
    - パイプライン/テスト環境/本番環境
- メトリクスの種類
    - 真偽値/離散値/時系列・履歴値
- 品質特性
    - ISO特性など

### 実装例
以下は私が構築しているパフォーマンス等を評価する適応度関数の一例

- 適応度関数の概要
    - [goreplay](https://github.com/buger/goreplay)を用いて本番環境へのリクエストの一部を転送する仕組みを導入
    - STGブランチにマージされたアプリケーションをCI上からテスト環境へdeployし、上記からリクエストを100rps程度受信する（以下このアプリを性能評価環境と呼ぶ）
    - prometheusを通して性能評価環境のメトリクス監視を実施
        - レイテンシ、HTTPステータスコードのエラー率、CPU利用率、メモリ利用率、システムエラー発生回数
    - これにより、改修されたアプリケーションが本番相当のリクエストを受けた際に、定義した閾値を下回らないこと常時確認可能

- 関数の区分
    - 規模
      - ホリスティック
    - 実行契機
      - 継続的
    - 実行場所
      - テスト環境
    - メトリクスの種類
      - 真偽値
    - 品質特性
      - 信頼性
      - 機能適合性

その他の例としては、「[ArchUnit](https://www.archunit.org/)を利用して、設計方針外のパッケージ参照が行われていないかテストすることで保守性を担保する」「CI上でsnykによるOSSの脆弱性を通知することで、想定外のCVEが混入されていないことを担保する」などがあります。


## まとめ
開発したプロダクトと同じく、組織も作りっぱなしではなく、どんどん育てていきましょう。