定期的な対面ミーティング

2024年2月27日

通信技術の向上により、リモートファーストスタイルで働くチームが増加しており、この傾向はCOVID-19パンデミックによる強制的な隔離によってさらに加速されました。しかし、リモートで活動するチームであっても、対面での集まりは依然として有益であり、数ヶ月ごとに行うべきです。

リモートファーストチームでは、全員が別々の場所にいて、メール、チャット、ビデオ、その他のコミュニケーションツールを使用して完全にコミュニケーションを取ります。これには明確な利点があります。世界中からチームに人材を採用でき、育児の責任を持つ人々を巻き込むことができます。無駄な通勤時間は、生産的または回復的な時間に変えることができます。

しかし、リモートワークがどれほど得意であっても、最新の共同作業ツールがどれほど優れていても、チームの他のメンバーと同じ場所に勝るものはありません。人間の交流は、対面で行われる場合、常に豊かになります。ビデオ通話は、トランザクション的になりやすく、適切な人間関係を築くための雑談の時間がほとんどありません。このような深い絆がなければ、誤解は深刻な人間関係の困難に発展し、チームは全員が直接話し合うことができれば効果的に解決できる状況に陥ってしまう可能性があります。

リモートファーストワークで効果的な人々から私がよく見かけるパターンは、定期的な対面会議を確実に行うことです。これらの会議では、一緒に作業した方がうまくいく作業要素をスケジュールします。リモートワークは、単独での集中を必要とするタスクに効果的であり、最新のツールを使用すると、リモートペアリングを実行可能にすることができます。しかし、多くの人からの迅速なフィードバックを必要とするタスクは、全員が同じ部屋にいる場合、はるかに簡単になります。ビデオ会議システムでは、その深さのインタラクションを作成することはできません。コンピューター画面を見つめて、他の人が何をしているかを確認するのは疲れます。休憩のためにコーヒーを一緒に飲みに行く機会もなく、作業を中断することもできません。製品戦略に関する議論、システムアーキテクチャの調査、新しい分野の調査 - これらは、チームが集まったときによく行われるタスクです。

人々が効果的に協力するためには、お互いを信頼し、お互いにどれほど頼ることができるかを認識する必要があります。信頼は、同じ部屋にいるときに発生する可能性のある社会的合図がないオンラインでは、築きにくいものです。したがって、対面での集まりの最も価値のある部分は、スケジュールされた作業ではなく、コーヒーを飲みながらの雑談や昼食での懇親会です。主に仕事とは関係のない非公式な会話は、仕事のやり取りをより効果的にする人間的な接触を築きます。

これらのガイドラインは、対面のコンテンツがどのようなものであるべきかを示唆しています。一緒に働くことは、それ自体が価値があり、チームの結束の重要な部分でもあります。そのため、一緒にいることから得られる低レイテンシのコミュニケーションの恩恵を受けるタスクに焦点を当て、丸1日の作業を設定する必要があります。その後、休憩、非公式な雑談、オフィスから一歩外に出る機会のために、多すぎると思われる時間を含める必要があります。私は人工的な「チームビルディング」エクササイズを避けたいと思っています。理由は、私がそれらをどれほど嫌っているかというだけです。このような集まりを行う人々は、その後、全員が活気づき、それによって次の数週間でより効果的になることができるという価値を強調しています。

リモートチームは、遠く離れた場所に形成される可能性があり、メンバーが数時間の移動で分離されているのを見るのは一般的です。このようなチームの場合、私が使用する経験則は、2〜3か月ごとに1週間集まることです。チームが経験を積んだ後、頻度を減らすことを決定するかもしれませんが、チームが年に少なくとも2回の対面会議を開催していない場合は心配です。チームがすべて同じ都市にいるが、通勤を減らすためにリモートファーストスタイルを使用している場合は、より短い集まりを編成し、より頻繁に行うことができます。

この種の集まりは、オフィススペースの構成方法を再考することにつながる可能性があります。パンデミック以降、オフィスがはるかに使用されていないことについて、多くのことが語られてきました。オフィスは、日常の作業スペースではなく、この種の不規則なチームの集まりの場所になる可能性があります。これにより、柔軟で快適なチームの集まりスペースが必要になります。

一部の組織は、このようなチームの集会のための旅費や宿泊費に躊躇するかもしれませんが、彼らはそれをチームの有効性への投資と考えるべきです。これらの対面を無視すると、チームが行き詰まり、間違った方向に進み、紛争に悩まされ、人々がやる気を失います。これと比較して、飛行機やホテルの節約は誤った経済です。

参考文献

リモートファーストはリモートワークの1つの形式であり、リモートワークとオフィスワークで、さまざまなスタイルのリモートワークとそのトレードオフについて説明しています。

Thoughtworksでは、約20年前にオフショア開発センターを初めて開設したときに、リモートチームの定期的な対面集会の重要性を学びました。これらは、アジャイルソフトウェアプロセスとオフショア開発の活用で説明するプラクティスを生み出しました。

リモートワーク、特にタイムゾーンをまたがる場合は、非同期のコラボレーションパターンがより重要になります。プロダクトマネージャーである私の同僚、Sumeet Mogheは、彼の著書非同期ファーストプレイブックで、これを行う方法を詳細に説明しています。

ソフトウェア製品会社であるAtlassianは、最近、リモートワークに完全に移行し、経験に関するレポートを公開しました。彼らは、チームが年に約3回対面で集まることが賢明であることを学びました。Claire Lewは、2018年にリモートファーストチームを調査し、回答者の4分の1が「年に数回」リトリートを行っていることに注目しました。37Signalsは、20年近くにわたってリモートファースト企業として運営されており、年に2回、ミートアップをスケジュールしています

謝辞

Alejandro Batanero、Andrew Thal、Chris Ford、Heiko Gerin、Kief Morris、Kuldeep Singh、Matt Newman、Michael Chaffee、Naval Prabhakar、Rafael Detoni、およびRamki Sitaramanは、社内メーリングリストでこの投稿の草案について話し合いました。


レガシーシーム

2024年1月4日

レガシーシステムで作業する場合、ソースコードを編集せずにシステムの動作を変更できる場所であるシームを識別して作成することが重要です。シームが見つかると、それを使用して依存関係を解消してテストを簡素化し、プローブを挿入して可観測性を高め、レガシーの置き換えの一環としてプログラムフローを新しいモジュールにリダイレクトできます。

Michael Feathersは、彼の著書レガシーコードを効果的に扱うの中で、レガシーシステムのコンテキストで「シーム」という用語を作り出しました。彼の定義:「シームとは、その場所を編集せずにプログラムの動作を変更できる場所です」

シームが役立つ例を次に示します。注文の価格を計算するためのコードを想像してみてください。

// TypeScript
export async function calculatePrice(order:Order) {
  const itemPrices = order.items.map(i => calculateItemPrice(i))
  const basePrice = itemPrices.reduce((acc, i) => acc + i.price, 0)
  const discount = calculateDiscount(order)
  const shipping = await calculateShipping(order)
  const adjustedShipping = applyShippingDiscounts(order, shipping)
  return basePrice + discount + adjustedShipping
}

関数`calculateShipping`は外部サービスにアクセスしますが、これは低速(かつ高価)であるため、テスト時にアクセスしたくありません。代わりに、スタブを導入して、各テストシナリオに対して既成の決定論的な応答を提供できるようにします。テストごとに異なる応答が必要になる場合がありますが、テスト内で`calculatePrice`のコードを編集することはできません。したがって、`calculateShipping`の呼び出しの周りにシームを導入する必要があります。これは、テストが呼び出しをスタブにリダイレクトできるようにするものです。

これを行う1つの方法は、`calculateShipping`の関数をパラメーターとして渡すことです

export async function calculatePrice(order:Order, shippingFn: (o:Order) => Promise<number>) {
  const itemPrices = order.items.map(i => calculateItemPrice(i))
  const basePrice = itemPrices.reduce((acc, i) => acc + i.price, 0)
  const discount = calculateDiscount(order)
  const shipping = await shippingFn(order)
  const adjustedShipping = applyShippingDiscounts(order, shipping)
  return basePrice + discount + adjustedShipping
}

この関数の単体テストでは、単純なスタブを代用できます。

const shippingFn = async (o:Order) => 113
expect(await calculatePrice(sampleOrder, shippingFn)).toStrictEqual(153)

各シームには、イネーablingポイントが付属しています。「1つの動作を使用するか、別の動作を使用するかを決定できる場所」[WELC]。関数をパラメーターとして渡すと、`calculateShipping`の呼び出し元にイネーablingポイントが開かれます。

これにより、テストがはるかに簡単になります。送料の異なる値を入力し、`applyShippingDiscounts`が正しく応答することを確認できます。シームを導入するために元のソースコードを変更する必要がありましたが、その関数をさらに変更してもそのコードを変更する必要はありません。変更はすべて、テストコードにあるイネーblingポイントで行われます。

関数をパラメーターとして渡すことが、シームを導入する唯一の方法ではありません。結局のところ、`calculateShipping`のシグネチャを変更することは困難であり、本番コードのレガシーコールスタックを通じて配送関数パラメーターをスレッド化したくない場合があります。この場合、サービスロケーターを使用するなど、ルックアップの方が適切な場合があります。

export async function calculatePrice(order:Order) {
  const itemPrices = order.items.map(i => calculateItemPrice(i))
  const basePrice = itemPrices.reduce((acc, i) => acc + i.price, 0)
  const discount = calculateDiscount(order)
  const shipping = await ShippingServices.calculateShipping(order)
  const adjustedShipping = applyShippingDiscounts(order, shipping)
  return basePrice + discount + adjustedShipping
}
class ShippingServices {
  static #soleInstance: ShippingServices
  static init(arg?:ShippingServices) {
    this.#soleInstance = arg || new ShippingServices()
  }
  static async calculateShipping(o:Order) {return this.#soleInstance.calculateShipping(o)}
  async calculateShipping(o:Order)  {return legacy_calcuateShipping(o)}
  // ... more services

ロケーターを使用すると、サブクラスを定義することで動作をオーバーライドできます。

class ShippingServicesStub extends ShippingServices {
  calculateShippingFn: typeof ShippingServices.calculateShipping =
     (o) => {throw new Error("no stub provided")}
  async calculateShipping(o:Order) {return this.calculateShippingFn(o)}
  // more services

次に、テストでイネーblingポイントを使用できます

const stub = new ShippingServicesStub()
stub.calculateShippingFn = async (o:Order) => 113
ShippingServices.init(stub)
expect(await calculatePrice(sampleOrder)).toStrictEqual(153)

この種のサービスロケーターは、関数ルックアップを介してシームを設定する古典的なオブジェクト指向の方法であり、ここでは他の言語で使用できるアプローチを示すために示していますが、TypeScriptやJavaScriptではこのアプローチを使用しません。代わりに、このようなものをモジュールに入れます。

export let calculateShipping = legacy_calculateShipping

export function reset_calculateShipping(fn?: typeof legacy_calculateShipping) {
  calculateShipping = fn || legacy_calculateShipping
}

次に、このようなテストでコードを使用できます

const shippingFn = async (o:Order) => 113
reset_calculateShipping(shippingFn)
expect(await calculatePrice(sampleOrder)).toStrictEqual(153)

最後の例が示唆するように、シームに使用する最適なメカニズムは、言語、利用可能なフレームワーク、そしてもちろんレガシーシステムのスタイルに大きく依存します。レガシーシステムを制御するには、レガシーソフトウェアへの影響を最小限に抑えながら、適切な種類のイネーブリングポイントを提供するために、コードにさまざまなシームを導入する方法を学ぶ必要があります。関数呼び出しは、このようなシームを導入する簡単な例ですが、実際にははるかに複雑になる可能性があります。チームは何ヶ月もかけて、使い古されたレガシーシステムにシームを導入する方法を考え出すことがあります。レガシーシステムにシームを追加するための最適なメカニズムは、グリーンフィールドで同様の柔軟性を実現するために私たちが行うこととは異なる場合があります。

Feathersの著書は、主にレガシーシステムをテスト対象にすることに焦点を当てています。なぜなら、それは多くの場合、レガシーシステムを健全な方法で操作できるようにするための鍵となるからです。しかし、シームにはそれ以上の用途があります。シームがあれば、レガシーシステムにプローブを配置して、システムの可観測性を高めることができます。 `calculateShipping` への呼び出しを監視し、使用頻度を把握し、結果を個別の分析のためにキャプチャしたい場合があります。

しかし、おそらくシームの最も価値のある用途は、レガシーから動作を移行できることです。シームは、高価値顧客を別の送料計算機にリダイレクトする可能性があります。効果的なレガシーの置き換えは、レガシーシステムにシームを導入し、それらを使用して動作を徐々に最新の環境に移行することに基づいています。

シームは、新しいソフトウェアを作成するときにも考慮すべきことです。結局のところ、すべての新しいシステムは遅かれ早かれレガシーになるからです。私の設計アドバイスの多くは、適切に配置されたシームを使用してソフトウェアを構築することについてです。そうすれば、簡単にテスト、監視、および拡張できます。テストを念頭に置いてソフトウェアを作成すると、適切なシームのセットが得られる傾向があります。そのため、テスト駆動開発は非常に便利な手法です。


ソフトウェアとエンジニアリング

2023年12月13日

私のキャリアを通して、人々はソフトウェア開発を「伝統的な」エンジニアリングと比較してきました。通常、ソフトウェア開発者が適切な仕事をしていないことを叱責する方法でです。電子工学の学位を取得した私にとって、これはキャリアの初期に共感を覚えました。しかし、この考え方は、ほとんどの人がエンジニアリングの実際 workings について間違った印象を持っているため、欠陥があります。

Glenn Vanderburg は、これらの誤解を深く掘り下げることに多くの時間を費やしてきました。ソフトウェア開発をエンジニアリングと比較したい人は、彼の講演Real Software Engineering を視聴することを強くお勧めします。また、ポッドキャストOddly Influencedでの彼のインタビューを聞く価値もあります。残念ながら、彼にこの資料を書いてもらうことはできませんでした。素晴らしい記事になるでしょう。

この関係についての良い考えを持つもう一人は、Hillel Wayneです。彼は、従来のエンジニアリングとソフトウェアの両方で働いていた「クロスオーバー」の人々にインタビューしました。彼は、Are We Really Engineers? から始まる一連のエッセイで、学んだことを書き留めました。


テスト駆動開発

2023年12月11日

テスト駆動開発(TDD)は、テストを作成することでソフトウェア開発をガイドするソフトウェア構築の手法です。これは、Kent Beck によって1990年代後半にエクストリームプログラミングの一部として開発されました。本質的に、私たちは3つの簡単な手順を繰り返し実行します

  • 追加したい次の機能のテストを作成します。
  • テストに合格するまで機能コードを作成します。
  • 新しいコードと古いコードの両方をリファクタリングして、適切に構造化します。

多くの場合、*レッド - グリーン - リファクタリング*と要約されるこれら3つの手順がプロセスの核心ですが、最初にテストケースのリストを作成するという重要な初期手順もあります。次に、これらのテストの1つを選択し、それに赤-緑-リファクタリングを適用し、完了したら次を選択します。テストを適切に順序付けることはスキルであり、設計の重要なポイントに迅速に導くテストを選択する必要があります。プロセスの途中で、思いついたときにテストをリストに追加する必要があります。

XPE2 がテストファーストプログラミングと呼ぶ、最初にテストを作成することには、2つの主な利点があります。最も明らかなのは、自己テストコードを取得する方法であるということです。なぜなら、テストに合格するために機能コードを作成することしかできないからです。2つ目の利点は、最初にテストについて考えることで、最初にコードへのインターフェースについて考えることを強制されることです。インターフェースとクラスの使用方法に焦点を当てることで、インターフェースと実装を分離することができます。これは、多くのプログラマーが苦労している優れた設計の重要な要素です。

TDDを台無しにする最も一般的な方法は、3番目のステップを怠ることです。コードをクリーンに保つためにリファクタリングすることは、プロセスの重要な部分です。そうでなければ、コードフラグメントの乱雑な集まりになってしまいます。(少なくともこれらにはテストがあるので、ほとんどの設計の失敗よりも苦痛が少ない結果になります。)

参考文献

ケントのTDDを行うための標準的な方法の要約は、重要なオンライン要約です。

さらに深く理解するには、Kent Beckの著書テスト駆動開発を参照してください。

James Shoreのアジャイル開発の芸術の関連章は、効果的なアジャイル開発の残りの部分にも関連付けられている別の健全な説明です。ジェームズはまた、Let's Play TDDと呼ばれる一連のスクリーンキャストを作成しました。

改訂

このページの最初の投稿は2005-03-05でした。ケントの標準的な投稿に触発されて、2023-12-11に更新しました


差分デバッグ

2023年12月4日

回帰バグは、しばらくの間存在していたソフトウェアの機能に新しく出現したバグです。それらを追跡する場合、通常、ソフトウェアのどの変更がそれらの出現を引き起こしたかを把握することが重要です。その変更を調べることで、バグがどこにあるのか、どのように修正するのかについて貴重な手がかりを得ることができます。この形式の調査にはよく知られた用語はありませんが、私はそれを差分デバッグと呼んでいます。

差分デバッグは、コードがバージョン管理されている場合にのみ機能しますが、幸いなことに、最近はそれが標準となっています。しかし、それを効果的に機能させるために必要なことがいくつかあります。古いバージョンのソフトウェアを簡単に実行できるように、再現可能なビルドが必要です。高頻度統合により、小さなコミットがあると非常に役立ちます。そうすれば、問題のあるコミットが見つかったときに、何が起こったのかをより簡単に絞り込むことができます。

バグを生み出したコミットを見つけるには、まずバグのない過去のバージョンを見つけます。これを*last-good*バージョンとしてマークし、現在のバージョンを*earliest-bad*としてマークします。次に、2つの間のコミットの半分を見つけ、バグがあるかどうかを確認します。ある場合、このコミットはearliest-badになり、そうでない場合はlast-goodになります。問題のあるコミットが見つかるまで、プロセス(「半区間」または「バイナリ」検索)を繰り返します。

gitを使用する場合、git bisectコマンドはこの多くを自動化します。バグの存在を示すテストを作成できる場合、git bisectもそれを使用して、問題のあるコミットを見つけるプロセス全体を自動化できます。

プログラミングセッション内で差分デバッグが役立つことがよくあります。実行に数分かかる遅いテストがある場合、最も関連性の高いテストのサブセットのみを実行して30分間プログラミングする可能性があります。グリーンテストの実行ごとにコミットする限り、それらの遅いテストの1つが失敗した場合に差分デバッグを使用できます。長期的な履歴のためにそれらをスカッシュするのが最善だと感じても、非常に頻繁にコミットすることの価値はこれです。一部のIDEは、バージョン管理へのコミットよりもきめ細かいローカル履歴を自動的に保持することで、これを容易にします。

改訂

このページは、2004-06-01に最初に投稿しました。元の形式では、それはどちらかというとカジュアルな経験レポートでした。用語の定義に近づけるために、2023-12-04に書き直しました。差分デバッグは業界であまり普及していない用語ですが、それを説明するために一般的に使用されている別の用語は見たことがありません。


チームトポロジー

2023年7月25日

大企業のソフトウェア資産など、大規模なソフトウェア開発には多くの人員が必要です。多くの人員がいる場合は常に、効果的なチームに分割する方法を考え出す必要があります。ビジネスケイパビリティ中心のチームを形成することで、ソフトウェア開発は顧客のニーズに迅速に対応できますが、必要なスキルの範囲は、多くの場合、そのようなチームを圧倒します。チームトポロジーは、Matthew SkeltonとManuel Paisによって開発された、ソフトウェア開発チームの組織を記述するためのモデルです。これは、4つの形式のチームと3つのモードのチームインタラクションを定義します。このモデルは、ビジネスケイパビリティ中心のチームが価値のあるソフトウェアの安定した流れを提供するというタスクで成功できるように、健全なインタラクションを促進します。

このフレームワークにおける主要な種類のチームは、単一のビジネスケイパビリティのソフトウェアを担当するビジネスケイパビリティ中心のチームである**ストリームアラインチーム**です。これらは長期にわたるチームであり、ビジネスケイパビリティを強化するためのソフトウェア製品を提供するものとして、彼らの努力を考えています。

各ストリームアラインドチームは、フロントエンド、バックエンド、データベース、ビジネス分析、機能の優先順位付け、UX、テスト、デプロイ、監視など、ソフトウェア開発の全て(エンチラーダ全体)を担当する、フルスタックかつフルライフサイクルのチームです。彼らは、ビジネス分析、テスト、データベースなどの機能に焦点を当てたアクティビティ指向チームではなく、ビジネス成果に焦点を当てた成果指向です。しかし、彼らはあまりにも大規模であってはならず、理想的にはそれぞれがツーピザチームであるべきです。大規模な組織には、このようなチームが多数存在し、それぞれがサポートするビジネス機能は異なりますが、データストレージ、ネットワーク通信、オブザーバビリティなどの共通のニーズがあります。

このような小規模なチームでは、認知負荷を軽減する方法が必要であり、データストレージの問題などではなく、ビジネスニーズのサポートに集中できるようにする必要があります。これを行う上で重要なのは、これらの焦点ではない懸念事項を処理するプラットフォーム上に構築することです。多くのチームにとって、プラットフォームは、データベースを基盤とするWebアプリケーション向けのRuby on Railsなど、広く利用可能なサードパーティ製のプラットフォームになる可能性があります。しかし、多くの製品では、利用できる単一の既製のプラットフォームがないため、チームは複数のプラットフォームを見つけ、統合する必要があります。大規模な組織では、さまざまな内部サービスにアクセスし、企業標準に従う必要があります。

この問題は、組織向けの内部プラットフォームを構築することで addressed することができます。このようなプラットフォームは、サードパーティサービス、ほぼ完全なプラットフォーム、および内部サービスの統合を行うことができます。チームトポロジーは、これを構築するチームを(想像力に欠けるが賢明に)**プラットフォームチーム**として分類します。

小規模な組織は、外部から提供された一連の製品の上に薄いレイヤーを生成する単一のプラットフォームチームで作業できます。ただし、大規模なプラットフォームには、ツーピザで供給できるよりも多くの人員が必要です。そのため、著者は、多くのプラットフォームチームの**プラットフォームグループ**について説明する方向に移行しています。

プラットフォームの重要な特徴は、主にセルフサービス方式で使用されるように設計されていることです。ストリームアラインドチームは、依然として製品の運用に責任を負っており、プラットフォームチームとの elaborate なコラボレーションを期待することなく、プラットフォームの使用を指示します。チームトポロジーフレームワークでは、このインタラクションモードは**X-as-a-Serviceモード**と呼ばれ、プラットフォームはストリームアラインドチームへのサービスとして機能します。

しかし、プラットフォームチームは、顧客のニーズを深く理解した上で、サービス自体を製品として構築する必要があります。これには、多くの場合、サービスを構築している間、異なるインタラクションモードである**コラボレーションモード**の1つを使用する必要があります。コラボレーションモードは、より intensive なパートナーシップ形式のインタラクションであり、プラットフォームがx-as-a-serviceモードに移行するのに十分成熟するまでの temporary なアプローチと見なす必要があります。

これまでのところ、このモデルは特に独創的なものを表しているわけではありません。組織をビジネス指向チームとテクノロジーサポートチームに分割することは、エンタープライズソフトウェアと同じくらい古いアプローチです。近年、多くの著者が、これらのビジネス機能チームにフルスタックとフルライフサイクルの責任を負わせることの重要性を表明しています。私にとって、チームトポロジーの輝かしい洞察は、フルスタックでフルライフサイクルのビジネス指向チームを持つということは、多くの場合、過剰な認知負荷に直面することを意味し、それが小規模で応答性の高いチームへの欲求に反しているという問題に焦点を当てていることです。プラットフォームの主な利点は、それが*この認知負荷を軽減する*ことです。

チームトポロジーの重要な洞察は、プラットフォームの主な利点は、ストリームアラインドチームの認知負荷を軽減することです

この洞察は、 profound な意味を持ちます。まず、プラットフォームチームがプラットフォームについてどのように考えるべきかを変えます。クライアントチームの認知負荷を軽減することで、主に標準化またはコスト削減を目的としたプラットフォームとは異なる設計上の決定と製品ロードマップにつながります。プラットフォーム以外にも、この洞察により、チームトポロジーはさらに2種類のチームを特定することで、モデルをさらに発展させています。

一部の機能には、多くのストリームアラインドチームにとって重要なトピックを習得するために considerable な時間と労力を費やすことができるスペシャリストが必要です。セキュリティスペシャリストは、ストリームアラインドチームのメンバーとして可能であるよりも多くの時間をセキュリティ問題の調査とより広範なセキュリティコミュニティとの対話に費やす可能性があります。そのような人々は**イネーブリングチーム**に集まり、その役割は他のチーム内で関連するスキルを伸ばすことであり、それらのチームは独立したままで、サービスをより適切に所有および進化させることができます。これを達成するために、イネーブリングチームは、主にチームトポロジーの3番目と最後のインタラクションモードを使用します。**促進モード**にはコーチングの役割が含まれます。イネーブリングチームは、標準を作成して準拠を確保するためではなく、同僚を教育およびコーチングして、ストリームアラインドチームの自律性を高めるために存在します。

ストリームアラインドチームは、顧客の価値のストリーム全体に責任を負いますが、ストリームアラインドチームの作業の側面で、それに焦点を当てる dedicated なグループが必要となるほど demanding なものがあり、4番目で最後のタイプのチームである**複雑なサブシステムチーム**につながることがあります。複雑なサブシステムチームの目標は、その複雑なサブシステムを使用するストリームアラインドチームの認知負荷を軽減することです。そのサブシステムのクライアントチームが1つしかない場合でも、それは価値のある division です。ほとんどの複雑なサブシステムチームは、x-as-a-serviceモードを使用してクライアントと対話しようとしますが、短期間はコラボレーションモードを使用する必要があります。

チームトポロジーには、チームとその関係を示す一連のグラフィカルシンボルが含まれています。ここに示されているものは、現在の標準からのものであり、書籍で使用されているものとは異なります。最近の記事では、これらの図の使用方法について詳しく説明しています。

チームトポロジーは、コンウェイの法則の影響を明示的に認識して設計されています。それが奨励するチーム組織は、人間とソフトウェア組織の相互作用を考慮に入れています。チームトポロジーの支持者は、そのチーム構造がソフトウェアアーキテクチャの将来の開発を、ビジネスニーズに合わせた応答性が高く、疎結合されたコンポーネントに形作ると考えています。

ジョージ・ボックスは巧みに皮肉りました。「すべてのモデルは間違っている、いくつかは役に立つ」。したがって、チームトポロジーは間違っています。複雑な組織は、わずか4種類のチームと3種類のインタラクションに単純に分割することはできません。しかし、このような制約こそがモデルを役に立つものにしているのです。チームトポロジーは、人々が組織をより効果的な運用方法に進化させることを促すツールであり、ストリームアラインドチームが認知負荷を軽減することでフローを最大化できるようにするものです。

謝辞

Andrew Thal、Andy Birds、Chris Ford、Deepak Paramasivam、Heiko Gerin、Kief Morris、Matteo Vaccari、Matthew Foster、Pavlo Kerestey、Peter Gillard-Moss、Prashanth Ramakrishnan、およびSandeep Jagtapは、社内メーリングリストでこの投稿の草案について議論し、貴重なフィードバックを提供しました。

Matthew SkeltonとManuel Paisは、この投稿について詳細なコメントを提供してくれました。書籍出版以降の彼らの最近の考えを共有してくれたことも含んでいます。

参考文献

チームトポロジーフレームワークの最良の扱いは、2019年に出版された同名の書籍です。著者はまた、チームトポロジーのWebサイトを運営し、教育およびトレーニングサービスを提供しています。チームインタラクションモデリングに関する彼らの最近の記事は、チームトポロジー(メタ)モデルを使用して組織のモデルを構築および進化させる方法の良い入門書です。[1]

チームトポロジーの多くは、認知負荷の概念に基づいています。著者は、Tech Beaconで認知負荷について調査しました。Jo Pearceは、認知負荷がソフトウェア開発にどのように適用されるかについて詳しく説明しました。

チームトポロジーのモデルは、私がこのサイトで公開したソフトウェアチーム組織に関する多くの考え方とよく一致しています。これは、チーム組織タグにまとめてあります。

注記

1: モデリング用語をより厳密に言えば、チームトポロジーは通常**メタモデル**として機能すると言えます。チームトポロジーを使用して航空会社のソフトウェア開発組織のモデルを構築する場合、そのモデルは、チームトポロジーの用語に従って分類された航空会社のチームを示します。それから、チームトポロジーモデルは私の航空会社モデルのメタモデルであると言います.


ツーピザチーム

2023年7月25日

ツーピザチームとは、特定のビジネス機能のソフトウェアを完全にサポートする小規模なチームです。この用語は、Amazonがソフトウェアスタッフをどのように組織したかを説明するために使用されたため、普及しました。

名前は、そのようなチームの最も明白な側面である、その規模を示唆しています。この名前は、チームは2枚のピザで賄える人数を超えてはならないという原則に由来しています。(ただし、ここではアメリカのピザについて話しています。初めてこちらで出会ったときは、驚くほど巨大に見えました。)チームを小さく保つことで、チームの結束力を維持し、緊密な協力関係を築くことができます。通常、これはそのようなチームが約5〜8人であることを意味すると聞いていますが、私の経験では、上限は約15人です。

名前はサイズにのみ焦点を当てていますが、チームの焦点も同様に重要です。ツーピザチームは、他のチームへのハンドオフと依存関係を最小限に抑えながら、ユーザーに価値のあるソフトウェアを提供するために必要なすべての機能を備えている必要があります。彼らは顧客のニーズを理解し、それをすぐに動作するソフトウェアに変換し、顧客のニーズの変化に合わせてソフトウェアを実験および進化させることができます。

ツーピザチームは、アクティビティ指向ではなく、成果指向です。彼らはスキルのライン(データベース、テスト、運用)に沿って組織化するのではなく、顧客をサポートするために必要なすべての責任を負います。これにより、機能が顧客に流れる際のチーム間のハンドオフが最小限に抑えられ、サイクルタイム(機能のアイデアを実行中のコードに変換するために必要な時間)を短縮できます。この成果指向はまた、彼らが本番環境にコードをデプロイし、そこでその使用状況を監視することを意味し、有名なのは、あらゆる本番環境の停止に対して責任を負うことです(多くの場合、時間外サポートに責任を負うことを意味します)。これは、「あなたが構築したものは、あなたが実行する」という原則として知られています。

このように顧客のニーズに焦点を当てるということは、チームが長寿命であることを意味し、ビジネス機能中心のチームは、その機能がアクティブである限り、そのビジネス機能をサポートします。ソフトウェアが「完成」したときに解散するプロジェクト指向のチームとは異なり、彼らは自分たちを長寿命の製品を可能にし、強化するものと考えています。この側面から、彼らはしばしば**製品チーム**と呼ばれます。

ツーピザチームが製品をサポートするために必要なスキルの範囲と責任の広さは、そのようなチームがチーム組織への主要なアプローチになり得るとしても、適切に構築されたソフトウェアプラットフォームからのサポートが必要であることを意味します。小規模な組織の場合、これは最新のクラウドオファリングなどの商用プラットフォームになる可能性があります。大規模な組織は、ツーピザチームが困難なハンドオフを作成することなくコラボレーションできるように、独自の内部プラットフォームを作成します。チームトポロジーは、ツーピザチーム(チームトポロジーでは**ストリームアラインドチーム**と呼びます)をサポートするために必要なさまざまな種類のチームとインタラクションについて考えるための良い方法を提供します。

ビジネスケイパビリティ中心のチームが効果的に機能するためには、互いのケイパビリティを活用する必要があります。そのため、チームは、多くの場合、綿密に設計されたAPIを通じて、同僚に自身のケイパビリティを提供する必要があります。このような、チームが同僚にサービスを提供する責任は、しばしば見落とされますが、これが行われないと、硬直化した情報サイロにつながります。

このようにビジネスケイパビリティを中心に人を組織することは、コンウェイの法則の影響により、組織のソフトウェアの構成方法と深く関わっています。ツーピザチームによって構築されたソフトウェアコンポーネントは、同僚との相互作用を適切に制御し、明確なAPIを介して連携する必要があります。この考え方がマイクロサービスの開発につながりましたが、それが唯一のアプローチではありません。モノリシックなランタイム内で適切に構造化されたコンポーネントの方が、多くの場合、より良い方法です。