PHPカンファレンス福岡2023
@hanhan1978レガシー回避のPHP開発術保守性の高いアプリケーションを作る方法2023-06-24 PHPカンファレンス福岡
View Slide
@hanhan1978● 富所 亮● 所属株式会社カオナビBackEnd Re-architecturing Team (BERT)● 職業バックエンドエンジニア● ブログhttps://blog.hanhans.net● Yokohama North AMhttps://anchor.fm/yokohama-north-am2
レガシーとはなにか?3
4レガシーの定義
5“レガシーコードとは、単にテストの無いコードです。”
6“毎日実行され、過去の意思決定をもとにのがれようのない影響を及ぼし続けるが、なんの活力もないようなコードがある。それを丁寧な言葉で「レガシー」と呼ぶ。”
7“保守または拡張が困難な既存のプロジェクトなら、なんでも「レガシー」(legacy)と呼ぶことにしている”
8“創業期の資金不足や人材不足によって生じたコード上の課題全般を、広義のレガシーコードと定義”
まとめると9
● テストが無い● 活力が無い● 保守・拡張が困難10
11これらの性質が一つでもあればレガシーなのか?
12白黒はつかないAll or Nothing ではない。
13● レガシーではない部分(計画的に設計・実装)● レガシーな部分(涙を飲んだ部分)FIXME, TODOなど● レガシーな部分(知らなかった、未認識)実際にはアプリケーション内に良い箇所・悪い箇所が混在する
14思考停止は危険全体をまとめてレガシーと表現してしまうと「さあ!フルリニューアルだ!」という話にしかならない
15場合によってはフルリニューアルは合理的な判断だが大抵の場合はコストがかかりすぎる→ かつ、その組織で1から作ってレガシーになったのよね?
16場合によってはフルリニューアルは合理的な判断だが大抵の場合はコストがかかりすぎる→ かつ、その組織で1から作ってレガシーになったのよね?歴史に学べ!!!
17この登壇内でのレガシーの扱い
18● テストが無い● 活力が無い● 保守・拡張が困難これらを「レガシーな性質」と呼ぶ。
19アプリケーション内にある「レガシーな性質」の割合に目を向ける全体を包含して、思考停止しないこと
20レガシーな性質≒技術的負債ただ、このままだと解像度が低い
21● 自然には少なくならない● 時間とともに勝手に増えるレガシーな性質の特性
22「改善しないと、改善されないんだよ?」ねぇ知ってる?
23レガシーな性質を減らす活動をしないといけない
24レガシーを回避するとは?
25ソフトウェア開発の目的はレガシー回避ではない
26● テストがあり● 活力があり● 保守・拡張が容易これらは必ずしも必須ではない
27プロダクトアウト+カスタマーサクセスが目的-> みんなでアジャイル
28ただしレガシーな性質を放置すると目的達成の足を引っ張るようになる
29現状、達成されていることにも目を向けましょうね。ところで
30● 希望● 利益● 人々の生活● ビジョンこれらを達成できていないものはレガシーにもなれていない
31● 希望● 利益● 人々の生活● ビジョンこれらを達成できていないものはレガシーにもなれていない良い面にもきちんとフォーカスを当てましょう
32なるようになって、今がある
33ソフトウェアが達成したい目的はそれぞれ作られてきたコンテキストも様々
34そのソフトウェアを作ってきた歴史がある作ってきたチームがある経済活動をしてきた結果として今がある
35そのアプリケーションに不満があるかもしれない体制に不満があるかもしれないやり方に不満があるかもしれない
36それはそれで、ある種安定した状態単純に、レガシーな性質を悪とみなして活動しても、うまくいかんぞ!
37無計画な開発による意図しない副作用https://www.coastalwiki.org/wiki/Human_causes_of_coastal_erosion
38テストがないことが普通の場所で、テストがあることを普通にしようとするのは、不自然な行為(サバンナをのぞく)
39現状維持しがち● 今はこれで動いているんだから● 今までこれでやってきたから● 変更するのは大変だから正常性バイアスとの戦い
40”当たり前”を変える必要がある
41例● リファクタリング● PHPStan対応● Accessibility対応● フレームワークのバージョンアップ● プログラミング言語のバージョンアップ● CIの速度改善
42ここまでのまとめ
43● レガシーはソフトウェアの性質● なるようになったものは変わりづらい
44レガシーな性質を減らすには、そもそもレガシーを生み出す既存の流れ全体に抗う必要がある。局地戦で改善できるほど甘い相手ではない
ソフトウェアはどうやって作られるか?45
460 -> 1 のフェーズ
47● リリースが命● 動くことが最優先
48色々とない● 金がない● 開発者がいないあるのは達成したいこと
49目先の対応が求められる> 個社対応
50● 人材も環境も不十分● ドメインが安定していない「レガシーコードとの付き合い方」における課題はこのフェーズで大量に生み出される
511->10のフェーズ
52ちょっと余裕がでてくる● 開発者の採用にお金を使える● 安定したドメインが出来てくる商売になる黄金パターンが生まれてくる
53ソフトウェアの状態まだ、ビッグリライトをする余地がある
54技術的負債の要因とその効果Software Architecture Metrics / Oreilly & Associates Inc, 2022
55技術的負債の要因とその効果Software Architecture Metrics / Oreilly & Associates Inc, 2022リプレースで一気に負債を返済
56● 事業成長が求められる● 機能がどんどん追加されるこのフェーズの先には、リプレース作戦を取るのが非現実的になるくらいに、システムの横のサイズが増える
57このフェーズで、「リリース優先なので...」を連発すると、改善の難易度がバク上がりする
58技術的負債の要因とその効果Software Architecture Metrics / Oreilly & Associates Inc, 2022リプレースが非現実的になるほど、機能が増えて、複雑度が増す
5910->100 のフェーズ
60市場をある程度押さえてきた状態さらに市場を取りに行くために、採用にコストをかけてチームを増やす組織も大きくなる。
61● どんどん機能が増える!● リプレースは、非現実的になる。● レガシー解消のコストも大きい● 結局リリース優先の圧力は強い単純に、影響が大きすぎる&同時並行で開発しているものが多すぎて改善活動を諦めだす
62リプレースが出来ないならどうする?
63【一発逆転】銀の弾丸を探す現実逃避● サービス分割● 一部機能をSaaSに寄せる● マイクロサービス??● モジュラーモノリス● Rustで書き直す
64いわゆる茹でガエル
65● なんかCI重いな?● なんか開発に時間かかるな● なんか色々面倒くさいなこんなことをひしひしと感じているフェーズ
66積み上がるレガシーを肌で感じるビジネスとしての成功と、開発効率のバランスを上手にとる必要がある
67ここまでのまとめ
68ソフトウェアは、社会を良くするという動機を持って誕生して、だれかの役に立つことで、経済活動がなりたつようになって、どんどん開発が進んで行く
69レガシーな性質は、普通に開発しているだけで積み上がっていく。そして、改善活動はソフトウェアの開発プロセス上は優先度の高くない活動。
ソフトウェアの各フェーズで何が積み上がるのか?70
710 -> 1 のフェーズ
72知識不足によるインフラ面、ソフトウェア設計面の負債とにかく最速で作って動かすことが重視されている
73反面、そのときのモダンなスタックで作られているので、経年劣化は起きてない。ソフトウェアの中身や、インフラ構成(カネがない)で「とにかくリリース優先」の影響を受ける
74総じて、レガシーな性質は少なく、打ち手は多いが、やる人がいない、指摘する人がいない
75例● フロントエンドの人しかいないので、全部 Firebase● ベンチャー優遇の、謎SAASを使っている● ノーコードのツール類を組み合わせたキメラ構成
761->10のフェーズ
77開発者が増える。このフェーズで、インフラのうまい載せ替えなどをすると、負債は一気に減る。例 コンテナ化、イミュータブルインフラストラクチャー化など
78技術的負債の要因とその効果(再掲)Software Architecture Metrics / Oreilly & Associates Inc, 2022
79ソフトウェア自体が機能数が少ない状態なので、大胆な施策も取りやすい。このタイミングで、機能開発全振りにしてしまうと、大胆な施策が取りにくくなる
80単純にデータ量も少ないので、色々やりやすい一方で、セカンドシステム症候群にとらわれる可能性
81負債解消のゴールデンタイムであるため、アレもコレもと欲が出る
82例● 俺たちの考えた最強のインフラ(最強ではない● 俺たちの考えた最強のアーキテクチャー(最強ではない● 俺たちの考えた最強の.... (最強ではない● プログラミング言語変更 (変更できない
83一見して、簡単に倒せそうなサイズ感に見えてしまうため、きちんとやろうとしすぎる
84結果として、拡張性のないアーキテクチャーが出来上がったり、一品物のカスタマイズインフラが出来てしまい、採用に困るような名品が作られる
8510->100 のフェーズ
86基本的には 1->10 のフェーズと同じだが、ビジネスドメインの安定がさらに進む会社の各組織が大きくなり、コミュニケーションコストが上がる。
87失敗したときのコストが、内外に対して上がるこのあたりまでにレガシーな性質が解消されずに残っている場合、追加で時の試練を受け始める
88例)● ソフトウェアのバージョン問題● フレームワークのバージョン問題● OSのバージョン問題● 問題のあるデータベース設計● 取り返しの付かない仕様ハレーション
89時間経過によって、モダンの概念が変わってくる仮想サーバー -> コンテナ化分散システム -> マイクロサービス
90今やるなら当然コレという方式がでてきており、何もしてなかったからレガシーになりましたという状態
91若手優秀層は、隣の芝生は青いな〜っとなる。つねにデバフを食らっている状態
92このフェーズでは、チーム数や関連する人間の数も増えているいかなる改善を行うにもコストが大きい
93チーム内合意では不十分で、横断的合意が必要となる新規加入するメンバーのオンボーディングが問題になるのもこの頃
94加入するメンバー数が多いので、教育に携わるメンバーも増やす必要があるEM的なポジションが不在 or EM的な性質を持ったメンバーがいなくなると、フォローが減る
95とにかく、問題が多いので、ソフトウェアのレガシーな性質に対する関心も低いチーム内で上手くやることが大事になるレガシーな性質もサイロ化
なぜ、改善されないのか?96
97> 改善活動を行わない限り、メンテナンスコストは上がる当然ですが、開発にはコストがかかります。コストの大半は人件費開発は、つまり開発者を金で雇って、ソフトウェアに変更を行うこと
98開発コストに、改善活動は含まれるか?スクラム開発では、スプリント内に、チームが主体的に改善活動を意図的に取り入れているチームもありますが、大半のチームは、そんな余裕はありません。受託では......
99質とスピード
100質とスピードは両立するhttps://speakerdeck.com/twada/quality-and-speed-2022-spring-edition
101質とスピードは両立するhttps://speakerdeck.com/twada/quality-and-speed-2022-spring-editionそれが出来るチームならな!
102大半のチームは、質とスピードの境地に達していないせいぜい、APoSD における戦術的プログラマーと同じ状態複雑性は上がるけど、とりあえず要件は満たす
103ほとんどの会社において、とりあえず要件は満たすという開発チームが必要最低限のレベルすくなくともリリースが出来るなら、経営陣としては問題なく見える
104ほとんどの会社において、とりあえず要件は満たすという開発チームが必要最低限のレベルすくなくともリリースが出来るなら、経営陣としては問題なく見えるソフトウェアのやばさは、目に見えにくい
105チームの基本行動
106ディレクションチームリードデザイナーQCプログラマー● インフラ● バックエンド● フロントエンド● アプリいわゆる開発チームチームトポロジーにおけるストリームアラインドチーム
107場合によっては、ここにマネージャーというさらに高次のマネジメントを行う人がいたり、スクラムやっている場合は、スクラムマスターやPOがいる
108さて、このチームだけで、レガシーを促進せずに開発がやれるか?ほとんどの場合、このチームはメンテナンスコストを足す方向に開発します。
109改善は、このチームの第一目的ではないこのチームは、顧客に価値を提供するために機能開発を行うOSのアップデートとか、脆弱性対応は優先度としては一段下がる
110技術的負債の要因とその効果Software Architecture Metrics / Oreilly & Associates Inc, 2022負債がたまる方向にしか行動しない
111チームにおこる変化
112上手くいっているチーム
113機能開発は行えるチームが、仮にうまくまわっていたとする収益があがるので、企業はさらに投資を行う。さらに市場を取りに行く。
114投資をすると、会社は開発者を採用してチームを増やして、開発を複数並行では実行する。問題はそのやり方。
115よくあるパターンは、チーム解体
116バラして増やす
117バラして増やすやったぜ!3倍のアウトカム!(とはならない)
118TeamB, TeamC の2つのチームが新設当初のチームは解体されている同じスピードでの開発は期待できない
119増えた2チームは、同じスピード、少なくとも同じ品質で開発することが、投資した側からは期待される実際には人間関係の再構築役割の再定義などが起こるので、当初の効率は下がる
120チームにおこる変化2
121● メンバー離脱● メンバー同士の相性問題● 評価への不満買い手市場であるエンジニアは、自分が適切に評価されていないと感じると、すぐに転職する
122PHPの主戦場であるインターネット業界では、平均勤続年数は4年前後https://web-camp.io/magazine/archives/77694
ここまでの話のポイント123
124みんなの大好きなクリーンアーキテクチャーの話も、イミュータブルインフラストラクチャーの話も、アジャイルもスクラムも出てきません。オブジェクト指向とかも知りません。
125そんなものに関係なくサービスの成長と共にソフトウェアはレガシーな性質を貯める方向に成長していく
126ところでレガシーな性質が溜まりすぎるとどうなるか?
127Bobおじさんの著書 Clean Craftsmanship には、倫理の話がでてくる。つまり、プログラマーが匠としての意識、高い倫理を保たず、テストも書かず、現状が悪化するにまかせた場合、どうなるか?
128例1. Volkswagen の改ざんソフトウェア2. HealthCare.gov におけるパフォーマンス問題3. Knight Capital の誤発注による倒産
レガシーを積み上げにくくする129メモ、ここから30分かかる
130全てに先立つ意識顧客中心主義ソフトウェアだけを見てはいけない。良い価値提供という北極星を忘れないように。
131それって、精神論?いやいや、誰も技術を軽んじたりしてない。極端に考えるのはNG
132https://mtx2s.hatenablog.com/entry/2023/04/26/230917
133証明できるのか?
134プロジェクトを改善をした状態、改善をしてない状態で、それぞれ計測しないと、改善の効果は証明できない?そんなこと不可能では?
135マインドチェンジ正常性バイアスとの正しい向き合い方
136> 改善を止めようとするなら現状維持のメリットをださないといけない
137Q レガシーな性質を保持し続けるメリットを教えてください?A 無いなら改善が必要だよね?
138戦略面の打ち手
139チームを大切にTeam First
140うまくいっているチームを解散させない改善を活動内に含むことができるような強いチームがこの世でもっとも大切-> まじで解散させるのはサイコパス
141教育施策1. オンボーディングの充実2. ドメイン知識の共有・促進化策3. チーム横断のコミュニケーション施策
142組織変更機能開発を主とせず、横断的にDevOpsを行うチームの結成なども候補にはあがる
143ただ、職能組織でワークしてないからって、横断的組織を作ったら即座にワークするわけではない。人による。チームトポロジーより> 職能集団はサイロ化する。
144ただ、職能組織でワークしてないからって、横断的組織を作ったら即座にワークするわけではない。人による。チームトポロジーより> 職能集団はサイロ化する。横断的組織もサイロ化する危険
145採用平均勤続年数が4年という世界線採用した人が4年経過する前に、新しい人を採用できないと開発が回せません。
146まとめ
1471. うまくいっているチームを解体しない2. プロだって、成果を出すには、時間がかかる3. 自主的な横断施策を行う人材を、大切にする
148組織変更だけはうまくいかない結局は人なので、横断的活躍をするラジカルなメンバーが内部に存在してくれる必要がある。
149戦術面でのうちて
150視野を広くもつこと● 🙅フロントエンドなのでバックエンドわからん● 🙅バックエンド専門なのでインフラわからん● 🙅インフラなのでアプリケーションはわからん
151問題は職能内に閉じないので、個人が自分の専門領域に閉じこもると解決が難しくなる。
152自分しか対応できるひとがいないという状況だったら、何が出来るか?-> 「出来ない」で蓋を閉じないで、自分の領域の横に手をのばすことが大切精神論ではない。最善を尽くせ!
153レガシーな性質が溜まりにくいアプリケーションの基本
15412 Factor APPまだまだ当たり前になっていない。先進的というよりは、それに従うことで、自然と運用・保守し易いアプリケーション+インフラ環境になるというイメージ
155https://12factor.net/ja/
156https://12factor.net/ja/
157計算機科学の知識● アルゴリズム● 空間計算量、時間計算量● プログラムがどのように実行されているのかの知識
158バグとは?積み上がったスタックの経路上で、想定外の状態が混入した結果
159Why Programs Fail / Morgan Kaufmann 2009
160Why Programs Fail / Morgan Kaufmann 2009型がついていると状態を確定しやすい早めの型付けで安心
161Working out loud問題はまず認識されることが必要なので、大声で叫べ!
162https://blog.studysapuri.jp/entry/2018/11/14/working-out-loud
163Slackが活発で、小さいやり取りが多いチームはコミュニケーションの問題が少ない(経験談)
164テストは書けテスト書くこと自体というよりは、テストを書きやすいコードに自然になるというのがポイントです。
165テスト書く -> 終わりではないTDDでコードを改善するための、最初の一歩がテストコードみんなもサバンナで暮らそうな!
166コレ一冊で、とりあえず現場では困らなくなる
167その先はコレ!みんなで付録Cの話をしよう!
168設計視点を持つ🙅ただコードを書けば良いという意識
169● 一貫性を保てているか?● 理解しやすいか?● 変更しやすいか?● 場当たり的な対応をしていないか?● 名前付けは妥当か?将来のために出来ることはたくさんある!
170クリーンアーキテクチャーや、DDDについての私見-> 特効薬ではない。トップダウン・アプローチとして使うとむしろ毒
171発想法からの指摘
172まず課題がある次に解決策がある課題を見ずに解決策を当てはめるのは🙅
173設計力をあげるには?ちょうぜつ本を読め!APoSDを読め!視野を広く!
174相談するコミュニティを頼って! PHP SlackPHPerRoom に、野生のPHPerがいるぞ!
175サーベイ系ちょっと真面目な技術選定の話
176この回、超おすすめ
177広く世間に知識を求めて少し良い技術選定が出来るように
カオナビ での取り組みを紹介178
179チーム横断課題への取り組み
180CTO室
181https://speakerdeck.com/kaonavi/growth-ready-engineering-team
182レビューマスター
183
184
185設計レビュー
186
187BERT設計相談会
188
189教育・採用への取り組み
190カタリバ (社内勉強会)
191
192kaonavi Tech Talk
193
194エンジニア採用
195
196
197アーキテクチャー施策
198Architecture Decision Record
199
200Package by Feature
201
202
203
204Feature Toggle
205
206その他、細かい施策
- PHPUnit- PHPStan- E2Eテスト- メトリクス取得- 書籍購入制度(ホンダナ)207
208今後目指したいこと
209GQM
210https://ieeexplore.ieee.org/document/5010301
211https://blog.hanhans.net/2023/05/29/gqm/
目的指向-> 企業のパーパスなどとすり合わせしやすい-> ただの数字から目的思考のメトリクスへ212
213まとめ
- レガシー化させないことは目的じゃない- 目的はもちろん達成する- かつ、レガシー化させない214
215https://speakerdeck.com/soudai/learn-from-predecessors
216救いがないと感じたとき、私は石切工が岩石を叩くのを見に行く。おそらく100回叩いても亀裂さえできないだろう。しかしそれでも100と1回目で真っ二つに割れることもある。私は知っている。その最後の一打により岩石は割れたのではなく、それ以前に叩いたすべてによることを。Pounding the rocks
217レガシーから目をそらすな!
@hanhan1978相談・指摘・その他 下記のTwitterアカウントにどうぞ218