Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
詳細の決定を遅らせつつ実装を早くする
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
shimabox
November 08, 2025
Programming
2
1.8k
詳細の決定を遅らせつつ実装を早くする
PHPカンファレンス福岡2025 の発表資料になります
#phpconfuk #hall_hz
shimabox
November 08, 2025
Tweet
Share
More Decks by shimabox
See All by shimabox
明示と暗黙 ー PHPとGoの インターフェイスの違いを知る
shimabox
2
1.1k
人には人それぞれのサービス層がある
shimabox
3
1.1k
自分のためから誰かのためへ
shimabox
10
4.3k
情報処理安全確保支援士をとった話
shimabox
1
260
クリーンアーキテクチャから見る依存の向きの大切さ
shimabox
5
2.4k
GoとPHPのインターフェイスの違い
shimabox
2
510
並行処理を学びGuzzleと仲良くなる
shimabox
3
2.7k
擬人化で完全に理解するクリーンアーキテクチャ
shimabox
20
12k
Unit of Workパターンで永続化とトランザクションを制御する
shimabox
11
7.8k
Other Decks in Programming
See All in Programming
それ、本当に安全? ファイルアップロードで見落としがちなセキュリティリスクと対策
penpeen
7
2.4k
OSSとなったswift-buildで Xcodeのビルドを差し替えられるため 自分でXcodeを直せる時代になっている ダイアモンド問題編
yimajo
3
590
MUSUBIXとは
nahisaho
0
110
大規模Cloud Native環境におけるFalcoの運用
owlinux1000
0
260
Vibe codingでおすすめの言語と開発手法
uyuki234
0
210
CSC307 Lecture 07
javiergs
PRO
0
530
Unicodeどうしてる? PHPから見たUnicode対応と他言語での対応についてのお伺い
youkidearitai
PRO
1
1k
ZJIT: The Ruby 4 JIT Compiler / Ruby Release 30th Anniversary Party
k0kubun
1
390
メルカリのリーダビリティチームが取り組む、AI時代のスケーラブルな品質文化
cloverrose
2
510
[KNOTS 2026登壇資料]AIで拡張‧交差する プロダクト開発のプロセス および携わるメンバーの役割
hisatake
0
220
MDN Web Docs に日本語翻訳でコントリビュート
ohmori_yusuke
0
620
20260127_試行錯誤の結晶を1冊に。著者が解説 先輩データサイエンティストからの指南書 / author's_commentary_ds_instructions_guide
nash_efp
0
810
Featured
See All Featured
How to train your dragon (web standard)
notwaldorf
97
6.5k
Building Adaptive Systems
keathley
44
2.9k
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
69
世界の人気アプリ100個を分析して見えたペイウォール設計の心得
akihiro_kokubo
PRO
66
36k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
61
49k
Principles of Awesome APIs and How to Build Them.
keavy
128
17k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
9.9k
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
100
WENDY [Excerpt]
tessaabrams
9
36k
Making Projects Easy
brettharned
120
6.6k
sira's awesome portfolio website redesign presentation
elsirapls
0
140
Transcript
詳細の決定を遅らせつつ 実装を早くする 2025/11/08 PHPカンファレンス福岡2025 しまぶ@shimabox
NAME: "しまぶ" SNS: "@shimabox" TAMASHII: "沖縄" COMPANY: "カオナビ" SKILL: -
"PHP" - "Go" FUKUOKA: "SB⚾, アビスパ⚽おめ" whoami.yml 2 はいさい
こんな経験はありませんか 3 ステークホルダー XXX画面作成の進捗は どうでしょうか? ステークホルダー (まだ!!?) おれたち ただいま絶賛DB設計中で...
こんな経験はありませんか 4 ステークホルダー XXX画面作成の進捗は どうでしょうか? ステークホルダー (まだ!!?) おれたち ただいま絶賛DB設計中で... まれによくある
「完璧なDB設計になるまで 実装を始められない」 「どの外部APIを選ぶべきか 決められず1ヶ月が経過」 「仕様が決まらないので 手を動かせない」 まれによくある 5
1. 境界を作る(インターフェース) 2. かんたんな実装で動かす(デモする) 3. フィードバックを得てから本実装 6 この3つのステップを使って解決していきます
なぜ、手が止まるのか 7 そもそも
8 なぜ手が止まるのか 完璧を求めすぎている (最初からいいものを作ろうとしている)
• 「最初から正解を出さないと...」 • 「失敗したくない...」 • 「後から変更できないと思っている」 9 なぜ手が止まるのか
完璧なもの、正解なんてものはない 10 気持ちはわかる、でもね
要求は変わる 11 完璧なもの、正解なんてものはない このサイクルを回したい 作 る 試 す 直 す
→ →
詳細の決定を遅らせつつ 実装を早くする 12 そこで
13 詳細の決定は後回し Clean Architecture 達人に学ぶソフトウェアの構造と設計 詳細の決定を遅らせろ • 詳細の決定は後回しにできる • いや、後回しにすべきだと
言っている
詳細 • DB, フレームワーク, UI, 外部ライブラリ(API), テスト, などなど • 本質的な目的に直接は貢献しないが、目的を実
現するのに必要な技術的なツールや仕組み • 詳細は目的ではなく、手段 14 詳細とはなんでしょう
これらは詳細 なので後回し 「完璧なDB設計になるまで 実装を始められない」 「どの外部APIを選ぶべきか 決められず1ヶ月が経過」 「仕様が決まらないので 手を動かせない」 15 まれによくある
なぜこれで実装が早くなるのか 16 詳細の決定を遅らせる
グルメ情報サイトを作る (福岡市に特化) 17 かんたんな例で見ていきます
イメージ 18 福岡市のグルメスポット
API定義を決める ↓ DB設計を考える ↓ アーキテクチャを考える ↓ 実装 19 よくある 実装まで終わっ
てから、フィー ドバックをもら う
• 「何を受け取って、何を返すか」 • OpenAPI Specification (OAS) を用意したりする 20 API定義を決める
{ "data": [ { "area_name": "中央区", "spots": [ { "id":
1, "name": "◯蘭 天神店", "category": "ラーメン", "location": "福岡市中央区天神x-x-x", "description": "天然とんこつラーメン専門店", "note": "xxxxx", "image_url": "/images/xxxxx.jpg" }, ] }, { "area_name": "博多区", "spots": [ {// 〜 }, {// 〜 }, {// 〜 } ] }, ] } 21 レスポンスJson (正常系)
22 よくある思考 「テーブル設計、クエリはどうしよ うかな」 「正規化は?インデックスは?」 ↓ 1週間経過...まだエンドポイントが 叩けない DB設計
これは詳細 「テーブル設計、クエリはどうしよ うかな」 「正規化は?インデックスは?」 23 DB設計
1. 境界を作る(インターフェース) 2. かんたんな実装で動かす(デモする) 3. フィードバックを得てから本実装 24 そこで、この3つのステップ
• 「何を受け取って、何を返すか」 25 API定義を決める(従来通り)
26 1. 境界を作る // インターフェースで境界を作る interface GourmetSpotInterface { public function
findAll(): array; } ポイント • 「何をするか」だけ定義 • 「どうやるか」は決めない
27 2. かんたんな実装 class InMemoryGourmetSpot implements GourmetSpotInterface { private array
$gourmetSpots = [ [ 'id' => 1, 'name' => '◯蘭 天神店', 'location' => '福岡市中央区天神x-x-x', // 〜 ], [ 'id' => 2, 'name' => 'うどん◯', 'location' => '福岡市博多区住吉x-xx-xxx', // 〜 ], [// 〜], [// 〜], , , ]; public function findAll(): array { return $this->gourmetSpots; } } DB設計は知らんけど、動く!
28 2.5 依存先を変える ここでテストを書いておくと良い class GourmetSpotController { public function __construct(
private GourmetSpotInterface $gourmetSpot ) {} public function index(): JsonResponse { $gourmetSpots = $this->gourmetSpot->findAll(); // エリア別にグルーピング → ビジネスロジック $groupedByArea = $this->groupByArea($gourmetSpots); return response()->json(['data' => $groupedByArea]); } private function groupByArea(array $gourmetSpots): array { // 住所から「中央区」「博多区」などを抽出 } }
29 デモをしてフィードバックを得る おれたち 動くもの作ったので 見てもらえますか? ステークホルダー うーん、料金とか評価とか 項目をもう少し増やしたいです おれたち 了解です!
デモをしてフィードバックを得る おれたち (とりあえず配列いじればいいか) (PHPの配列マジで神) 修正楽勝だな〜 おれたち 修正したので 見てもらえますか? ステークホルダー ぺきかん!
30
// フィードバックを得た上で実装 class GourmetSpot implements GourmetSpotInterface { public function findAll():
array { // この中でDBを触っていく // インターフェースを守っていれば、 試行錯誤が可能 // ----- 以下の選択肢がある ----- // DBじゃなくていいかも // 誰でも編集できるようにファイルでいいかも } } 31 3. フィードバックを得てから本実装 選択肢を残せる / Controllerの修正は不要
32 よくある 詳細の決定を遅らせる • Week 1 ◦ API定義を決める • Week
2 ◦ DB設計、アーキテクチャを考 える • Week 3 ◦ ようやく実装開始 • Week 4 ◦ そしてデモ ↓ 1ヶ月後にやっとフィードバック • Week 1 ◦ API定義を決める • Week 2 ◦ インターフェース定義 ◦ メモリ実装 ◦ デモ ↓ 2週間目からフィードバック! • Week 3以降 ◦ 確信を持って設計、本実装
ステークホルダー 福岡市のお天気情報を表示す るようにしてください おれたち (お天気情報はどこから?) (そもそも必要なんか?) APIは何を使いますか? それが...まだ決まってないです なにかが降ってきた 33
イメージ 34 福岡市のグルメスポット ☀ 23℃(お出かけ日和です) これ
35 やっぱり、この3つのステップ 1. 境界を作る 2. かんたんな実装で動かす 3. フィードバックを得てから本実装
{ "temperature": 23, "weather": "sunny", // これで画像を決める "message": "お出かけ日和です" }
36 API定義を決める
37 1. 境界を作る interface WeatherServiceInterface { // モデルを返す(配列でもいいけど) public function
getWeather(): Weather; } ポイント • OpenWeatherMap? WeatherAPI? 気象庁API? → 後で決める!
38 2. かんたんな実装 class MockWeatherService implements WeatherServiceInterface { public function
getWeather(): Weather { // APIは呼ばずにモデルを返す return new Weather( temperature: 23, weather: 'sunny' ); } } APIの仕様は知らんけど、動かす!
39 2. かんたんな実装 final class Weather { public function __construct(
public readonly int $temperature, public readonly string $weather ) {} public function toArray(): array { return [ 'temperature' => $this->temperature, 'weather' => $this->weather, 'message' => $this->message(), ]; } // ビジネスロジック private function message(): string { return match ($this->weather) { 'sunny' => $this->temperature > 20 ? 'お出かけ日和です' : '少し肌寒いです', default => '今日も一日頑張りましょう' }; } } モデルは単独でテストが書ける!
class GourmetSpotController { public function __construct( private GourmetSpotInterface $gourmetSpot, private
WeatherServiceInterface $weatherService ) {} public function index(): JsonResponse { $gourmetSpots = $this->gourmetSpot->findAll(); $groupedByArea = $this->groupByArea($gourmetSpots); $weather = $this->weatherService->getWeather(); return response()->json([ 'data' => $groupedByArea, 'weather' => $weather->toArray() ]); } private function groupByArea(array $gourmetSpots): array {} } 40 2.5 依存先を変える ここでもテストは書いておく
うーん、、いらないです 了解です!(やっぱりな) デモをしてフィードバックをもらう 41 仮実装のおかげで • 外部API契約してない • 複雑な実装はしてない •
✅ すぐ削除できる
42 3. 採用となってもフィードバックを得ているので実装に入れる class WeatherService implements WeatherServiceInterface { public function
getWeather(): Weather { // 外部APIを叩いて本物のデータを取得 // キャッシュしたりとかも // (実際はHTTPクライアント使う) $data = file_get_contents('https://api.xxxx.org/...'); return $this->createWeather($data); } private function createWeather($data): Weather {}; } 差し替えるだけ
43 よくある 詳細の決定を遅らせる • Week 1-2 ◦ どのAPIを使うか悩む ◦ 料金は?
レスポンス速度は? • Week 3 ◦ 実装開始 • Week 4 ◦ デモ ↓ 「やっぱり、いらないです」🔥 • Week 1 ◦ 仮実装でデモ ◦ 「やっぱり、いらないです」✅ または、 • Week 1 ◦ 仮実装でデモ「よいですね!」 • Week 2-3 ◦ 仕様明確 → API選定👍 → 実装 フィードバックが早いと、 無駄なし!
白状します。 外部APIの選定に1ヶ月以上かけたことがあります。 APIの使い方や、料金、レスポンス速度ばかり調べてい ました。 今となればもう少しうまく進めることが出来たんじゃな いかなぁと反省しながら喋っています。 44 昔の思い出
閑話休題 45
46 アプローチをふりかえる
47 アプローチをふりかえる 1. 境界を作る (詳細の決定は後回し)
48 アプローチをふりかえる 2. 仮実装 (動くものを早く作る)
49 アプローチをふりかえる 3. 本実装 (確信を持って実装)
質問 「必ずインターフェースを用意しな いといけないの?」 50 唐突にQ&A
51 回答:必ずしも必要ではない ベタ書きでもOK • まずは動かすことが大事 • 変わらなそうであればコントローラにベタ書き 詳細はあとでじっくり考えたいところ • 変わりそうなものと、変わらないものを分ける
• そこに境界を作る
52 境界(抽象)をひくのは難しい • 変わりそうなものと、変わらないものを分ける • そして、変わらないものに依存したい • 抽象は変わらないものとして用意したい 抽象は安定化させたい(が、これが難しい)
53 完成までは難しい • PHPの配列は最強だからといって、そのままだ と辛い、Immutableにしたい • グルメスポット一覧は、`GourmetSpot[]` な どで表現できるようになるといい •
動くものは早く作れるけど、完成が早くなると は言っていない
まとめ 54
55 今日話したこと ✅ 詳細の決定は後回しにできる (今まで先に悩んでいたところ) ✅ インターフェースで境界を作れば 実装の置き換えが可能、試行錯誤も可能 ✅
動くものを早く作ると、フィードバックも早まる
56 動くものを早く作ると、フィードバックも早まる ↓ 早期のフィードバックで間違った方向へ進むのを 防げる だいじなこと
57 1. 境界を作る 2. かんたんな実装で動かす 3. フィードバックを得てから本実装 このパターンを身につければ 仕様が未確定でも、手は動かせるはず💪 この3つのステップを試してみよう
58 完璧なもの、正解なんてものはない 手を動かしていきましょう💪 この3つのステップで何かを作ってみてほしい 1. 境界を作る 2. かんたんな実装で動かす 3. フィードバックを得てから本実装
X @shimabox 59 おわりに この発表も「完璧を目指さず」 作られました。 私自身、まだ実践の途中です。 フィードバックをお待ちしてい ます。
60 📖 共著で本を書いています 📖(時間があれば宣伝)
ご清聴ありがとうございました 61