Slide 1

Slide 1 text

組織もソフトウェアも難しく考えない、 もっとシンプルな考え方で設計する PHPカンファレンス福岡2025 Hideki Kinjyo GitHub: o0h / X: @o0h_ [公開用] v1.2.2

Slide 2

Slide 2 text

今日のお話  2

Slide 3

Slide 3 text

今日のお話  3

Slide 4

Slide 4 text

俺みたいな 「ソフトウェアも組織も同じように考えたい」 ってやつ、他に、いますか  4

Slide 5

Slide 5 text

なぜ、そんな話なのか 「フィードバック」とやらに注目すると、 何かに役立てられるんでない?  ソフトウェアにも組織にも  5 今日のお題

Slide 6

Slide 6 text

おしながき §1 定義:フィードバックって何だ!? @5分 §2 活用:フィードバックを設計に活かす @10分 §3 発展:組織もソフトウェアも @8分 §4 エピローグ @3分  6

Slide 7

Slide 7 text

自己紹介 • 金城秀樹 / きんじょうひでき • GitHub: @o0h / 𝕏 : @o0h_ • 好きなFWはCakePHP • アイコンは美味しい鮭親子丼の写真です • 最近はPodcastをやっています • ハッシュタグ: #readlinefm  

Slide 8

Slide 8 text

§1 定義:フィードバックって何だ!? §3 活用:フィードバックを設計に活かす §3 発展:組織もソフトウェアも エピローグ

Slide 9

Slide 9 text

ここからの話 このトークにおける「フィードバックとは何か」を話していきます。 1. 形式・構造的なフィードバックの定義 2. フィードバックにはどんな意義があるのか  9

Slide 10

Slide 10 text

フィードバックって何のこと? そもそも!

Slide 11

Slide 11 text

最初に結論 フィードバックとは 何かをすると、 何かをされた対象から、 反応が返ってくる 構造のこと  11

Slide 12

Slide 12 text

いくつかの例を見てみましょう  12

Slide 13

Slide 13 text

フィードバックの素朴な形  13 こんにちは! (にっこり)

Slide 14

Slide 14 text

フィードバックの素朴な形  14 ラーメンください へい、 お待ちぃ!

Slide 15

Slide 15 text

↑ 概論ここまで ↓ ここから具体例  15

Slide 16

Slide 16 text

組織とソフトウェアに見るフィードバック

Slide 17

Slide 17 text

組織で見るフィードバック①  17 こういうのが 欲しい〜 作ったぞ〜〜! PdM DEV

Slide 18

Slide 18 text

組織で見るフィードバック②  18 最近多い 顧客の声を教えて 集計データどうぞ! PdM CS

Slide 19

Slide 19 text

ソフトウェアにおけるフィードバック①  19 クラスA クラスB メソッドX 結果

Slide 20

Slide 20 text

ソフトウェアにおけるフィードバック①  20 クラスA クラスB メソッドX 結果 何かをする 何かをされた 反応が返る

Slide 21

Slide 21 text

[ソ]フィードバック① $fp = Utils::tryFopen($file);   何かをする 何かをされた 反応が返る

Slide 22

Slide 22 text

[ソ]フィードバック② $version = $this->version;   プロパティへのアクセスも 「取得結果」がある 反応が返る 何かをされた 何かをする

Slide 23

Slide 23 text

[ソ]フィードバック③ try { $fp = fopen($file, $mode); } catch (Throwable $e) { $ex = new RuntimeException( sprintf( 'Unable to open %s w/%s', $file, $mode, ), previous: $e); }   例外のthrowもフィードバック 反応が返る 何かをする

Slide 24

Slide 24 text

現時点では、 「小さなフィードバック関係が沢山あるんだな」を 感じてもらえればOK  24

Slide 25

Slide 25 text

(形式的な定義は分かったけど) フィードバックにはどんな意義があるの? 何を もたらすのか?

Slide 26

Slide 26 text

フィードバックの意義と働き 「投げて返ってきたものを受け取る」 コレだけなら注目するまでもない  26

Slide 27

Slide 27 text

フィードバックの意義と働き 「投げて返ってきたものを受け取る」 コレだけなら注目するまでもない  フィードバックは何をもたらしているのか に注目したい  27

Slide 28

Slide 28 text

フィードバックの意義と働き 自身の目的を達成するために 適切な相手に働きかけ、 そのフィードバックから 自身の行動を調整できる ことが、フィードバックの意義  28

Slide 29

Slide 29 text

フィードバックの働き  29 お、良いボタンがある。 押してみようかな。ポチ〜 押すだけで 1000万円 当たるボタン 押す ◯◯サービスに 登録されました (月額30万円) 視覚に訴える めちゃヤバ案件 (変化)

Slide 30

Slide 30 text

フィードバックの働き 受け取った後に、 次の行動が促される  30 めちゃヤバ案件 逃げる? 問題を取り除く? 信じる? ◯◯サービスに 登録されました (月額30万円)

Slide 31

Slide 31 text

フィードバックの働き -より俯瞰して-  31 #phpconfuk #hall_hz で「FFBなう」って呟いて!今!! 🐦「FFBなう」 私 皆様

Slide 32

Slide 32 text

フィードバックの働き -より俯瞰して-  32 #phpconfuk #hall_hz で「FFBなう」って呟いて!今 🐦 なぜ、 「呼びかける」という 行動をしたのか?

Slide 33

Slide 33 text

フィードバックの働き -より俯瞰して-  33 そもそもの行動には、 起点となる目的がある で「FF 登壇した痕跡 残してぇ〜〜

Slide 34

Slide 34 text

登壇した痕跡 残してぇ〜〜 フィードバックの働き -より俯瞰して-  34 行動の結果として フィードバックを得る  次の行動は、 「目的」に照らし合わせて 調整される 「FFBなう」っ て呟いて! たくさん流れ てきた!! RePost.. RePost.. RePost.. RePost..

Slide 35

Slide 35 text

フィードバックの働き -より俯瞰して-  35 行動の結果として フィードバックを得る  次の行動は、 「目的」に照らし合わせて 調整される 登壇した痕跡 残してぇ〜〜 「FFBなう」っ て呟いて! あんま流れて こない。。。 早く!! 「FFBなう」って呟 いて!

Slide 36

Slide 36 text

↑ 概論ここまで ↓ ここから具体例  36

Slide 37

Slide 37 text

組織とソフトウェアに見るフィードバック

Slide 38

Slide 38 text

組織で見るフィードバック  38 法務 営業 ★法務には、自分のための目的があって 業務効率を 上げるぞ!

Slide 39

Slide 39 text

組織で見るフィードバック  39 ★ 行動を起こし、営業に働きかけを行う 業務効率を 上げるぞ! 契約書の 雛形を 更新したよ!

Slide 40

Slide 40 text

組織で見るフィードバック  40 ★ その結果が、フィードバックとして返ってくる 契約書の 雛形を 更新したよ! 使いにくい! 業務効率を 上げるぞ!

Slide 41

Slide 41 text

契約書の 雛形を 更新したよ! 使いにくい! 組織で見るフィードバック  41 ★ 目的に合わせて、フィードバックを次のアクションにつなげる 契約書の 雛形を 更新したよ! 共有・説明会を開こう! 業務効率を 上げるぞ!

Slide 42

Slide 42 text

契約書の 雛形を 更新したよ! 契約書の 雛形を 更新したよ! 組織で見るフィードバック  42 ★ 目的に影響を与えないフィードバックは影響を及ぼさない 経費精算 大変すぎる〜 ふーん 業務効率を 上げるぞ!

Slide 43

Slide 43 text

[ソ]フィードバック $version = $this->getVersion(); if ($version->lt($minVersion)) { return false; } return true;  

Slide 44

Slide 44 text

[ソ]フィードバック $version = $this->getVersion(); if ($version->lt($minVersion)) { return false; } return true;   「バージョンどうですか?」 の入力 $version = $this->getVersion(); $version->lt($minVersion)

Slide 45

Slide 45 text

[ソ]フィードバック $version = $this->getVersion(); if ($version->lt($minVersion)) { return false; } return true;   true or falseの フィードバック $version->lt($minVersion)

Slide 46

Slide 46 text

[ソ]フィードバック $version = $this->getVersion(); if ($version->lt($minVersion)) { return false; } return true;   入力者側が、 フィードバック内容を見て 次のアクションを行う return false; return true;

Slide 47

Slide 47 text

[ソ]フィードバック function isSupported() { $version = $this->getVersion(); if ( $version->lt($minVersion) ) { return false; } return true; }   この手続きは 「バージョンで判定する」 という目的がある function isSupported()

Slide 48

Slide 48 text

§1 まとめ

Slide 49

Slide 49 text

このトークでの定義 フィードバックとは 何かをすると、 何かをされた対象から、 反応が返ってくる 構造のこと  49

Slide 50

Slide 50 text

もたらすもの 自身の目的を達成するために 適切な相手に働きかけ、 そのフィードバックから 自身の行動を調整できる ことが、フィードバックの意義  50

Slide 51

Slide 51 text

§1 定義:フィードバックって何だ!? §2 活用:フィードバックを設計に活かす §3 発展:組織もソフトウェアも エピローグ

Slide 52

Slide 52 text

ここからの話 「フィードバックを設計に活かす」ための観点を話していきます • フィードバックを受け取った後に何をしているか?が肝 • 受け取った後に「頑張っている」か「あまり苦労しない」か • 良いフィードバックであれば、苦労しないでそのまま使える • 良いフィードバックを受け取れる構造を作り込んでいく • 適切な責務分割を促し、凝集性を高める  52

Slide 53

Slide 53 text

(意義が分かったとして) フィードバックから何が分かるの? 何を もたらすのか?

Slide 54

Slide 54 text

フィードバックが「分かる」と何を得られるのか  54 入力者 システム 何かをする 反応を返す (フィードバック) こういう構造があって 何かをされた 最終出力

Slide 55

Slide 55 text

入力者 フィードバックが「分かる」と何を得られるのか  55 こう機能するところに システム 何かをする 反応を返す 目的 調整 何かをされた 最終出力

Slide 56

Slide 56 text

入力者 最終出力 フィードバックが「分かる」と何を得られるのか  56 この内容に注目して システム 何かをする 反応を返す 目的 調整 何かをされた

Slide 57

Slide 57 text

入力者 最終出力 フィードバックが「分かる」と何を得られるのか  57 ここの構造を変えるヒントとする システム 何かをする 反応を返す 目的 調整 何かをされた

Slide 58

Slide 58 text

ヒントはどこに眠っているのか 「本来の目的」と 「フィードバックを受け取った後」に注目する (どんな調整をしているか?どのくらい複雑か?)  そこには「本来の目的とのギャップ」がある  58

Slide 59

Slide 59 text

入力者 最終出力 本来の目的とのギャップ  59 目的 ここにギャップがあるから

Slide 60

Slide 60 text

入力者 最終出力 本来の目的とのギャップ  60 目的 調整 その調整にコストがかかる、という考え方

Slide 61

Slide 61 text

コストを下げるために良いフィードバックを 良いフィードバックであれば、 「本来の目的とのギャップ」が少なくなる  良いフィードバックを生み出す構造をつくる = 良い設計をする  61

Slide 62

Slide 62 text

↑ 概論ここまで ↓ ここから具体例  62

Slide 63

Slide 63 text

組織に見るフィードバックの活用例

Slide 64

Slide 64 text

組織で見るフィードバック  64 最近多い顧客の声を教えて 集計データどうぞ! 次の施策を考えるぞ〜 企画会議 (データを読み解か ないと。。) PdM CS

Slide 65

Slide 65 text

組織で見るフィードバック  65 最近多い顧客の声を教えて 集計データどうぞ! 次の施策を考えるぞ〜 企画会議 (データを読み解か ないと。。) 本当に必要なのはコッチっぽい

Slide 66

Slide 66 text

組織で見るフィードバック  66 最近多い顧客の声を教えて 集計データどうぞ! 次の施策を考えるぞ〜 企画会議 受け取った後に 「一手間」のコストがある (データを読み解か ないと。。)

Slide 67

Slide 67 text

組織で見るフィードバック  67 最近多い顧客の声を教えて 集計データどうぞ! 次の施策を考えるぞ〜 企画会議 「入出力」の発生も コストと見なせる

Slide 68

Slide 68 text

分析結果を踏まえて • 目的: 良い企画を考える(企画会議で提案する) • 現状の実装: CSからデータを取り寄せ、自分で解釈する • オーバーヘッド: • 受け取り後の分析コスト • CSとの一往復(欲しい内容の指示、出力結果の受信)  68

Slide 69

Slide 69 text

分析結果を踏まえて • 目的: 良い企画を考える(企画会議で提案する) • 現状の実装: CSからデータを取り寄せ、自分で解釈する • オーバーヘッド: • 受け取り後の分析コスト • CSとの一往復(欲しい内容の指示、出力結果の受信)  69 ここのコストの高さが、 「組織の構造から生じる問題」の大きさ

Slide 70

Slide 70 text

分析結果を踏まえて • 目的: 良い企画を考える(企画会議で提案する) • 現状の実装: CSからデータを取り寄せ、自分で解釈する • オーバーヘッド: • 受け取り後の分析コスト • CSとの一往復(欲しい内容の指示、出力結果の受信)  70 この構造を修正することで、 コストの総和を下げられないか?

Slide 71

Slide 71 text

組織の出力を低コストで支える構造  71 企画会議 構造を変更して、 より自然な「適応」を促す 顧客の声 インストール済み グロース全体像 インストール済み 次の施策を考えるぞ〜 PdM CS

Slide 72

Slide 72 text

ソフトウェアに見るフィードバックの活用例

Slide 73

Slide 73 text

ソフトウェアで見るフィードバック $productId = $request->get('product_id'); $result = $this->productApiClient->request($productId); $statusCode = $result->getStatusCode(); if ($statusCode >= 500) { return $this->error('Please try again later'); } elseif ($statusCode >= 400) { return $this->error('Unable to load product', 400); } $body = $result->getBody()->getContents(); $data = json_decode($body, true); if ($data['status'] === 'invalid') { return $this->error('Product unavailable', 404); } return $this->success(['product' => $data['detail']]);  

Slide 74

Slide 74 text

ソフトウェアで見るフィードバック $productId = $request->get('product_id'); $result = $this->productApiClient->request($productId); $statusCode = $result->getStatusCode(); if ($statusCode >= 500) { return $this->error('Please try again later'); } elseif ($statusCode >= 400) { return $this->error('Unable to load product', 400); } $body = $result->getBody()->getContents(); $data = json_decode($body, true); if ($data['status'] === 'invalid') { return $this->error('Product unavailable', 404); } return $this->success(['product' => $data['detail']]);   $this->productApiClient->request($productId); API Clientで 商品を取ってくる

Slide 75

Slide 75 text

ソフトウェアで見るフィードバック $productId = $request->get('product_id'); $result = $this->productApiClient->request($productId); $statusCode = $result->getStatusCode(); if ($statusCode >= 500) { return $this->error('Please try again later'); } elseif ($statusCode >= 400) { return $this->error('Unable to load product', 400); } $body = $result->getBody()->getContents(); $data = json_decode($body, true); if ($data['status'] === 'invalid') { return $this->error('Product unavailable', 404); } return $this->success(['product' => $data['detail']]);   $statusCode = $result->getStatusCode(); if ($statusCode >= 500) { return $this->error('Please try again later'); } elseif ($statusCode >= 400) { return $this->error('Unable to load product', 400); } HTTPステータスから エラーを判定&処理を中断する

Slide 76

Slide 76 text

ソフトウェアで見るフィードバック $productId = $request->get('product_id'); $result = $this->productApiClient->request($productId); $statusCode = $result->getStatusCode(); if ($statusCode >= 500) { return $this->error('Please try again later'); } elseif ($statusCode >= 400) { return $this->error('Unable to load product', 400); } $body = $result->getBody()->getContents(); $data = json_decode($body, true); if ($data['status'] === 'invalid') { return $this->error('Product unavailable', 404); } return $this->success(['product' => $data['detail']]);   $body = $result->getBody()->getContents(); $data = json_decode($body, true); if ($data['status'] === 'invalid') { return $this->error('Product unavailable', 404); } 応答本文から エラーを判定&処理を中断する

Slide 77

Slide 77 text

ソフトウェアで見るフィードバック $productId = $request->get('product_id'); $result = $this->productApiClient->request($productId); $statusCode = $result->getStatusCode(); if ($statusCode >= 500) { return $this->error('Please try again later'); } elseif ($statusCode >= 400) { return $this->error('Unable to load product', 400); } $body = $result->getBody()->getContents(); $data = json_decode($body, true); if ($data['status'] === 'invalid') { return $this->error('Product unavailable', 404); } return $this->success(['product' => $data['detail']]);   return $this->success(['product' => $data['detail']]); 商品情報を返す

Slide 78

Slide 78 text

受け取った後に「何をしているか」を分析する コントローラーが持っている仕事 • HTTPステータスからエラーを判定=>エラーを返す • 応答本文からエラーを判定=>エラーを返す • 商品情報を返す  78 Controller API Client 商品情報くれ〜 取ってきた結果〜 中身を精査しないと

Slide 79

Slide 79 text

受け取った後に「何をしているか」を分析する コントローラーが持っている仕事 • HTTPステータスからエラーを判定=>エラーを返す • 応答本文からエラーを判定=>エラーを返す • 商品情報を返す  79 目的ってコッチっぽくない?

Slide 80

Slide 80 text

受け取った後に「何をしているか」を分析する コントローラーが持っている仕事 • HTTPステータスからエラーを判定=>エラーを返す • 応答本文からエラーを判定=>エラーを返す • 商品情報を返す  80 本来の目的では無さそう!

Slide 81

Slide 81 text

本来の目的と非本来的なコスト $productId = $request->get('product_id'); $result = $this->productApiClient->request($productId); $statusCode = $result->getStatusCode(); if ($statusCode >= 500) { return $this->error('Please try again later'); } elseif ($statusCode >= 400) { return $this->error('Unable to load product', 400); } $body = $result->getBody()->getContents(); $data = json_decode($body, true); if ($data['status'] === 'invalid') { return $this->error('Product unavailable', 404); } return $this->success(['product' => $data['detail']]);   return $this->success(['product' => $data['detail']]); $productId = $request->get('product_id'); $result = $this->productApiClient->request($productId); return $this->error('Please try again later'); return $this->error('Unable to load product', 400); return $this->error('Product unavailable', 404); このあたりが「本題」で

Slide 82

Slide 82 text

本来の目的と非本来的なコスト $productId = $request->get('product_id'); $result = $this->productApiClient->request($productId); $statusCode = $result->getStatusCode(); if ($statusCode >= 500) { return $this->error('Please try again later'); } elseif ($statusCode >= 400) { return $this->error('Unable to load product', 400); } $body = $result->getBody()->getContents(); $data = json_decode($body, true); if ($data['status'] === 'invalid') { return $this->error('Product unavailable', 404); } return $this->success(['product' => $data['detail']]);   } $statusCode = $result->getStatusCode(); if ($statusCode >= 500) { このあたりが 「本題以外」と言える } elseif ($statusCode >= 400) { $body = $result->getBody()->getContents(); $data = json_decode($body, true); if ($data['status'] === 'invalid') { }

Slide 83

Slide 83 text

本来の目的と非本来的なコスト $productId = $request->get('product_id'); $result = $this->productApiClient->request($productId); $statusCode = $result->getStatusCode(); if ($statusCode >= 500) { return $this->error('Please try again later'); } elseif ($statusCode >= 400) { return $this->error('Unable to load product', 400); } $body = $result->getBody()->getContents(); $data = json_decode($body, true); if ($data['status'] === 'invalid') { return $this->error('Product unavailable', 404); } return $this->success(['product' => $data['detail']]);   「本題」は 全体の半分に満たない!

Slide 84

Slide 84 text

分析から見えてきたこと どんな問題が見えて来たのか • フィードバックを受け取ってからの処理が長い、煩雑 • => 目的のために利用するコストが高い(良いフィードバックになっていない) • 利用するために必要な知識が多様 • HTTPステータス・APIレスポンスの形式、と複数のレイヤーにまたがる • => 知識の多様化は高機能化をもたらし、目的を曇らせやすい  84

Slide 85

Slide 85 text

分析結果を踏まえて • コントローラーは 「商品情報を返す、ダメならエラーメッセージを」に集中させる • そのために新しいレイヤーを導入 • APIクライアントをラップしてエラー判定とかをよしなにやってくれる君 • 結果について持ち運んでくれる君(Resultオブジェクト)  85

Slide 86

Slide 86 text

ProductApiGateway: fetchメソッド public function fetch(int $productId): ProductApiResult { $result = $this->productApiClient->request($productId); $statusCode = $result->getStatusCode(); if ($statusCode >= 500) { return ProductApiResult::error('Please try again later'); } elseif ($statusCode >= 400) { return ProductApiResult::error('Unable to load product'); } $body = $result->getBody()->getContents(); $data = json_decode($body, true); if ($data['status'] === 'invalid') { return ProductApiResult::error('Product unavailable'); } return ProductApiResult::success($data['detail']); }  

Slide 87

Slide 87 text

ProductApiGateway: fetchメソッド public function fetch(int $productId): ProductApiResult { $result = $this->productApiClient->request($productId); $statusCode = $result->getStatusCode(); if ($statusCode >= 500) { return ProductApiResult::error('Please try again later'); } elseif ($statusCode >= 400) { return ProductApiResult::error('Unable to load product'); } $body = $result->getBody()->getContents(); $data = json_decode($body, true); if ($data['status'] === 'invalid') { return ProductApiResult::error('Product unavailable'); } return ProductApiResult::success($data['detail']); }   $statusCode = $result->getStatusCode(); if ($statusCode >= 500) { return ProductApiResult::error('Please try again later'); } elseif ($statusCode >= 400) { return ProductApiResult::error('Unable to load product'); } $body = $result->getBody()->getContents(); $data = json_decode($body, true); if ($data['status'] === 'invalid') { return ProductApiResult::error('Product unavailable'); } 中身は コントローラーで やっていた処理と 大体同じ

Slide 88

Slide 88 text

ProductApiGateway: fetchメソッド public function fetch(int $productId): ProductApiResult { $result = $this->productApiClient->request($productId); $statusCode = $result->getStatusCode(); if ($statusCode >= 500) { return ProductApiResult::error('Please try again later'); } elseif ($statusCode >= 400) { return ProductApiResult::error('Unable to load product'); } $body = $result->getBody()->getContents(); $data = json_decode($body, true); if ($data['status'] === 'invalid') { return ProductApiResult::error('Product unavailable'); } return ProductApiResult::success($data['detail']); }   ProductApiResult ProductApiResult::error('Please try again later'); ProductApiResult::error('Unable to load product'); ProductApiResult::error('Product unavailable'); ProductApiResult::success($data['detail']); 利用目的に合わせた 「ハイレベル」な表現で 結果を返す

Slide 89

Slide 89 text

Controller before/After $productId = $request ->get('product_id'); $result = $this ->gateway ->fetch($productId); if (!$result->isOk) { $this->error($result->reason); } else { $this->success([ 'product' => $data['detail'] ]); }   $productId = $request->get('product_id'); $result = $this ->productApiClient ->request($productId); $statusCode = $result->getStatusCode(); if ($statusCode >= 500) { return $this->error('Please try again later'); } elseif ($statusCode >= 400) { return $this->error( 'Unable to load product', 400 ); } $body = $result->getBody()->getContents(); $data = json_decode($body, true); if ($data['status'] === 'invalid') { return $this->error( 'Product unavailable', 404 ); } return $this->success(['product' => $data['detail']]);

Slide 90

Slide 90 text

構造が変更される 元々は大きなコストがControllerで発生していたのが…  90 Controller API Client 商品情報くれ〜 取ってきた結果〜 中身を精査しないと コスト高 コスト低

Slide 91

Slide 91 text

「良いフィードバック」のための調整が行われ、均等化・減少した 構造が変更される  91 Controller Gateway 商品情報くれ〜 取ってきた結果〜 Result API Client 中身を精査済み★ コスト激低 コスト低 コスト低 コスト激低

Slide 92

Slide 92 text

§3まとめ

Slide 93

Slide 93 text

フィードバックに注目して分析&設計する • フィードバックを受け取った後に何をしているかが肝 • 「何かたくさん頑張っているな」と思ったら、コストが高いと判断 • 目的に沿ったフィードバックになっていれば、コストが低くなる • 良いフィードバックを受け取れる構造を作り込んでいく • 適切な責務分割を促し、凝集性を高める  93

Slide 94

Slide 94 text

「フィードバックに注目する」ことの意義 • フィードバック(=何を受け取り、どう使っているか)には、 自身に本当に必要なこと・やりたいことが詰め込まれている • ここに着目して、より抽象レベルの「目的は何?」を可視化していく • 頭の中だけで概念的に考えるだけでなく、「実際に目の前にある活動」から「コ ストが大きい?小さい?」を捉えるヒントになる  94

Slide 95

Slide 95 text

§1 定義:フィードバックって何だ!? §2 活用:フィードバックを設計に活かす §3 発展:組織もソフトウェアも エピローグ

Slide 96

Slide 96 text

RT: 今日のお話  96

Slide 97

Slide 97 text

どちらにも通用するのはなぜか? どちらも 「目的」「フィードバック」「調整」という仕組み を共通して備えている  97

Slide 98

Slide 98 text

どちらにも通用するのはなぜか? 同じ仕組みを持つ = 同じ問題を持つ  同じアプローチが通用する  98

Slide 99

Slide 99 text

全く別々でも問題が似ている 問題は「要素間のやりとりから出るコスト」 (=> 受信後の調整コスト、やり取り自体のコスト)  コストの総和が大きくなれば、 トータルの出力が落ちる  99

Slide 100

Slide 100 text

やるべき事も似てくる 「良いやり取り」のための構造を作る 各所で、良いフィードバックを生み出させる  100

Slide 101

Slide 101 text

↑ 概論ここまで ↓ ここから具体例  101

Slide 102

Slide 102 text

実験: 「組織設計の見方」と 「ソフトウェア設計の見方」を 越境してみる

Slide 103

Slide 103 text

再掲: 先程の例  103 最近多い顧客の声を教えて 集計データどうぞ! 次の施策を考えるぞ〜 企画会議 (データを読み解か ないと。。)

Slide 104

Slide 104 text

UMLで書いてみるとこんな感じ?  104

Slide 105

Slide 105 text

UMLで書いてみるとこんな感じ?  105 getterを叩いているだけ

Slide 106

Slide 106 text

UMLで書いてみるとこんな感じ?  106 "ビジネスロジック"は 自前で持っている

Slide 107

Slide 107 text

擬似コードにするとこんな感じ? class PdM { private Cs $cs; public function createKikakuIdea(): Kikaku { $voiceCollection = $this->cs->getUserVoiceCollection(); // ͛͢ʔෳࡶͳͷͰ͜͜ʹ1,000ߦ͘Β͍ͷώϡʔϦεςΟοΫͳϩδοΫ͕ੜ͑Δ // $voiceCollectionΰχϣΰχϣɾɾɾͰɺ$kikakuΛಘΔ return $kikaku; } } }   ので

Slide 108

Slide 108 text

アンチパターンぽくないですか? 状況: • 「CS」は「顧客の声を取る」ための仲介者としてしか利用されない • その後、「PdM」は、複雑なビジネスロジックを適用する • 多分「集計して見やすくする」「考える」の仕事が入っていそうじゃない?  108

Slide 109

Slide 109 text

「ドメインモデル貧血症」的な見方 問題の形: • getterを提供しているだけでデータを使う知識がない • (悪い)結合や、(悪い)トランザクションスクリプトを誘発する なぜならば: • CSに「プロダクトを一緒に作る」という役割がない • ゆえに、「ただgetterを公開しているだけ」に成り下がっている それゆえ: • フィードバックを利用するためのコストを高めている  109

Slide 110

Slide 110 text

「機能の横恋慕的」な見方 問題の形: • 自身よりも、他のオブジェクトの機能やデータにばかり関心がある • 低凝集なオブジェクトの典型的な症状(不吉な臭い) なぜならば: • 「顧客の反応にアクセスする」のは「CSの機能」という思い込み • ゆえに、「わざわざCSを経由する」という教条的なコミュニケーションに陥る それゆえ: • 必要なデータを得る際にオーバーヘッドが生じている  110

Slide 111

Slide 111 text

組織構造のアーキタイプ これらの要素を組み合わせて、組織の「構造」が作られる • 公式な組織 - 部門、部署 • 組織図上に現れる単位 • 準公式な組織 - 時限的なプロジェクト、委員会 • 部署・部門と境界線を同一としない集約 • 会議体 / 会議 - 情報共有、意思決定のための集まり • アジェンダありきの単発・連続の集合 • 非公式なつながり - 偶発的な交流、(構造に用いる場合には)意図的な交流の仕組み • 業務上の結合に閉ざされない関係 • 組織パターン「冷水機」 スクラムパターン「おやつ神社」、Slackのtimesなども  111

Slide 112

Slide 112 text

どんな構造へのアプローチで、どう改善できる? ざっくりと考えて2つの方向性 1.「CS」を「プロダクト開発ドメイン」に組み込む 2.「顧客の声へのアクセス」を「CS」以外にも開放する  112

Slide 113

Slide 113 text

CS 1. 「CS」を「プロダクト開発ドメイン」に組み込む • 「プロダクト開発ドメイン」の拡張: CSの参画 • アーキタイプ「会議」や「チーム」でリファクタ  113 企画会議 顧客の声 インストール済み グロース全体像 インストール済み 次の施策を考えるぞ〜 PdM

Slide 114

Slide 114 text

2. 「顧客の声へのアクセス」を「CS」以外にも開放する • 「ロール-アクセスpermission」の見直し: PdMロールへの機能付与 • PdM-CS間の結合の解消  114 最近多い顧客の声を教えて 集計データどうぞ! 次の施策を考えるぞ〜 企画会議 データを取り出して 読み解く俺・・

Slide 115

Slide 115 text

共通する視点で見えてくるもの・改善方法がある • 組織の問題を「ソフトウェアっぽい知識」で解釈できた • フィードバックに着目した分析によって、 コミュニケーションの在り方にメスを入れる • より「本来の目的」とのギャップが少ない状態を目指す  115

Slide 116

Slide 116 text

§1 定義:フィードバックって何だ!? §2 活用:フィードバックを設計に活かす §3 発展:組織もソフトウェアも エピローグ

Slide 117

Slide 117 text

残っている話を回収 プロポーザルに書かれているのにノータッチになっている話に触れます  117

Slide 118

Slide 118 text

残っている話を回収 プロポーザルに書かれているのにノータッチになっている話に触れます  118

Slide 119

Slide 119 text

より一般化して捉えることの持つ力

Slide 120

Slide 120 text

(突然ですが) 統一理論って言葉があります  120

Slide 121

Slide 121 text

ChatGPT(GPT-5)の回答  121

Slide 122

Slide 122 text

一つの根本原理で、全てを理解する  122

Slide 123

Slide 123 text

「設計の小難しさ」をほぐしたい お仕事、難しいですよね  123

Slide 124

Slide 124 text

「設計の小難しさ」をほぐしたい - ビジネス領域、プロダクト領域の難しさ - 人間、組織領域の難しさ - 技術領域の難しさ  124 👀

Slide 125

Slide 125 text

「設計の小難しさ」をほぐしたい これらに共通する「力の流れ」が見えてくれば、 もっとシンプルに考えられるかもしれない  125

Slide 126

Slide 126 text

「設計の小難しさ」をほぐしたい これらに共通する「力の流れ」が見えてくれば、 もっとシンプルに考えられるかもしれない  逆に言えば、そうしなければ、 領域ごとの個別の理論を個別に暗記する、を強いられる  126

Slide 127

Slide 127 text

ここまでのトークで提示したもの シンプルに考えてみる、の1つの例として 「組織設計もソフトウェアも、 実は同じように問題を見抜けるはずなんだ」 というお話  127

Slide 128

Slide 128 text

「one of themな考え方」を超えて 自分なりの「全てを説明できる見方」を手に入れた時、 それは「とある1つの見方」を超えて 「哲学」「美学」になる  128

Slide 129

Slide 129 text

「one of themな考え方」を超えて 哲学 = 世界がどのようになっているか、という見方 美学 = 美しいと感じるもの、それはなぜか?の探求  129

Slide 130

Slide 130 text

色々な「哲学」の例  130 t-wadaさんの『技術選定の審美眼』 https://speakerdeck.com/twada/understanding-the-spiral-of-technologies-2025-edition

Slide 131

Slide 131 text

色々な「哲学」の例  131 k1LoWさんの 『ソフトウェア開発におけるインターフェイスという考え方』 https://speakerdeck.com/k1low/phperkaigi-2025

Slide 132

Slide 132 text

色々な「哲学」の例 クリストファー・アレグザンダーの 「パタン・ランゲージ」 「利用者参加の原則」  なぜ、建築の枠組みを超えて現れるのか  132 顧客が本当に 必要だったもの

Slide 133

Slide 133 text

お伝えしたかったこと 自分なりの哲学を持つことで、 生み出す設計に筋が通る。 それが設計の地力の向上につながる  133

Slide 134

Slide 134 text

お伝えしたかったこと なにか「哲学」と呼べる1つの軸を持つ。 色々な問題に素振りしてみる。 より深淵を覗き込んで、磨きをかけていく  134

Slide 135

Slide 135 text

まとめ

Slide 136

Slide 136 text

最後に言いたいこと 「フィードバックに着目せよ!」という方法、 面白いと思うので、 ぜひ遊んでみてください!  136

Slide 137

Slide 137 text

最後に言いたいこと が!!! そんなのはあくまで一例。 自分なりの哲学を見出してみてください!  137

Slide 138

Slide 138 text

おしまい! お付き合いいただき ありがとうございました!!

Slide 139

Slide 139 text

ご出演の皆さん from ゆるかわいい無料イラスト素材集 | いらすとん https://www.irasuton.com/ PdM CS 法務 営業 DEV

Slide 140

Slide 140 text

Appendix-Ⅲ 色々な「システム」

Slide 141

Slide 141 text

What's this • 今回の話の背景に、 「システムっぽいものとして対象を見る」という感覚があります • 発表では触れられていませんが、 枠外でちょっと整理しようかなと・・・  141

Slide 142

Slide 142 text

システム?  142 https://ja.wiktionary.org/wiki/システム

Slide 143

Slide 143 text

「システム」 一般に対するアプローチ • システムには • 「要素」がある • 要素同士の「繋がり」がある • 繋がった者同士の「相互作用」がある • 分析した要素の1つ1つだけを見ても、システムの理解は得難い • 代わりに、「繋がり」「相互作用」を見る必要がある  143

Slide 144

Slide 144 text

色々なシステム

Slide 145

Slide 145 text

サイバネティクス(古典的な) • https://ja.wikipedia.org/wiki/サイバネティックス • 「観察」「行動」「フィードバック」と「フィードバックを受けて制 御する」という構図 • 「フィードバックを結果として受けとり、自己の調整を行う」という 世界観  145

Slide 146

Slide 146 text

一般システム理論 • 還元主義(=要素を観察すれば、システムのすべてがわかる)を超えて、 「システムとは、要素の集合以上の意味を持つもの」の世界観 • 「一般的」な見方として、全体性・相互的な依存等の観点を適用する もの  146

Slide 147

Slide 147 text

G・M・ワインバーグの「一般システム思考入門」 • 「観察」を行う主体もシステムの一部であるという立場 • ("ネオ・サイバネティクス"と通ずるものがありそう • システムは、(依存関係にある)対象を「観察」して、自身の変化・適応を自律 的に行うもの • また、フラクタルな構造を持ち、ミクロなシステムは全て上位の「環境」の一 部である、という論も展開している • 「コード→パッケージ→ソフトウェア→インフラを含めたITシステム→ビジネス要求→ マーケットや現実世界→自然法則・宇宙」という感じに • 下位だけを見ると「変更」であっても、上位に対する「適応」にしか過ぎない  147

Slide 148

Slide 148 text

ノーマンの「行為の7段階理論」 • ゴールの形成 → 意図の形成 → 行為の詳細化 → 行為の実行 → 外 界の状況の知覚 → 外界の状況の解釈 → 結果の評価 • これも「フィードバックがあったときに、それを拾って、判断し、次 の行動に」という世界観と一致する  148

Slide 149

Slide 149 text

家族療法の「システムズアプローチ」 • 「問題は、個別の対象(クライエント)にあるのではなく、それをとり まく環境にある」という考えに基づくアプローチ • 例えば、「不登校の子ども」は「本人に原因がある」のではなく「家 族の接し方」に方策を求める、みたいな世界観 • つまり「個別の要素そのもの」ではなく「環境に変更を加える」。 それによって、「要素(=サブシステム)に流れる刺激が変わる→要素が 自律的な反応を起こす→問題の改善へ」という流れ  149

Slide 150

Slide 150 text

ヴァージニア・サティアの交流モデル • 取り込み→意味づけ→意義付け→反応という 構造 • 刺激(この発表で言うとフィードバックみた いなやつ)→それを受け取った人の解釈・評 価→結果に基づく行動 という構造としてモ デル化されている • 「ワインバーグのシステム洞察法」か「パー フェクトソフトウェア」あたりを読んでくだ さい  150

Slide 151

Slide 151 text

システム・ダイナミクス / システム思考  151 昨日ちょうど話があったっぽいから割愛!!

Slide 152

Slide 152 text

システム・ダイナミクス / システム思考  152 ヒューマンエラーの本を読んだ報告会 - Speaker Deck https://speakerdeck.com/o0h/funabashidev-1 関連する話題 これも読んで!

Slide 153

Slide 153 text

「システム的に物事を見る」と面白そうなこと

Slide 154

Slide 154 text

面白そう・可能性を感じること まだ自分の中で言語化しきれていませんが、 「もしかして、こういう風にソフトウェア設計を覗き込 んだら、見え方が変わってくるのではないか・・?」 と考えていたことをメモします  154

Slide 155

Slide 155 text

① システムは自律的に変化する • システムは「外部からの刺激を取り込み、それに対して内部からの適 応を図る」という捉え方 • なので、操作者が「手取り足取り動かす」ものではなく、主体的に変化する • かつ、そうした変動は経時的に起こる • 刺激→取り込み→適応、というのがシステムに蓄積されていく  155

Slide 156

Slide 156 text

② システムはブラックボックス • システムは「ブラック・ボックス」として動く • どういう評価基準・反応メカニズムを内部に持っているか?は、観察する側か らは見えない  156

Slide 157

Slide 157 text

①+② => システムは「どんな刺激が流れ込むか」次第 • 利用者がシステムに対してできることは、「境界線の外界から働きか ける」だけ • しかも、そうして流し込んだ刺激がどう取り込まれるか・何を起こす か?はブラックボックス • なので、利用者ができることは「システムの周辺・環境を整えること」 だけになる  157

Slide 158

Slide 158 text

この見方でソフトウェア設計を考えると • あるクラス設計や結合を考えるときに、 箱庭のように「このクラスは、どうやって育っていくだろうか」と眺 めることができそう • シムシティみたいなイメージ。区画や建造物を決めることはできるし、それに よって人口や生活に方向づけは出来るが、細部までは決めきれない。勝手に動 く  158

Slide 159

Slide 159 text

この見方でソフトウェア設計を考えると • 例えば • 「このクラスをこのnamespaceにおいたら、どんなメソッドが生えてきそうか な?」とか • 「クラス名を◯◯Managerにしたら、どんなメソッドが生えるだろう?」 • 未来のチームメンバーがどんなメソッドを"アリ"と捉えそうか • このあたりは「シグニファイア/アフォーダンス」っぽい感覚も伴う  159

Slide 160

Slide 160 text

この見方でソフトウェア設計を考えると つまるところ、 「クラスの内部(=要素への還元的な見方)」ではなく、 「それをとりまく環境が、どのような変化を促すか」 ・・・で掴めると、何か面白そうじゃないですか??  160