Slide 1

Slide 1 text

YAGNIのお話 9/26 PHP勉強会@東京 前田 和人

Slide 2

Slide 2 text

PHPConference2018 スピーカー募 集中です!

Slide 3

Slide 3 text

自己紹介 ■ 前田 和人 ■ @chiroruxxxx ■ 弁護士ドットコム株式会社

Slide 4

Slide 4 text

みなさんYAGNI知っていますか?

Slide 5

Slide 5 text

YAGNI実践してますか?

Slide 6

Slide 6 text

今回の内容 ■ 私は、なるべくYAGNIを心がけていますが・・・ ■ 結構むずかしい! ■ 実際に開発していて、自分でハマりかけたYAGNIポイントを2つお伝えしてい きます! ■ 熟練者の皆様はマサカリの準備をお願いいたします

Slide 7

Slide 7 text

ちなみにYAGNIとは ■ “You ain’t gonna need it” ■ (どうせ要らないって!) ■ 機能は実際に必要になるまで追加しないほうが良い ということ – 後で使う予定の機能の90%は実際に使用されない

Slide 8

Slide 8 text

実例

Slide 9

Slide 9 text

実例 ■ CSVのダウンロード機能を新規に実装したい ■ 別データのCSVダウンロード機能はすでに2つ存在している – しかも別々の実装で! ■ ⇒CSVダウンロードの機能を1つにまとめ、かつ新規の機能も実装する

Slide 10

Slide 10 text

とりあえず共通化 class CsvBuilder{ public function build($items, array $header): string { $stream = fopen('php://temp', 'w'); fputcsv($stream, $header); foreach ($items as $item) { fputcsv($stream, $item->toCsvRow()); } rewind($stream); return stream_get_contents($stream); } }

Slide 11

Slide 11 text

エンコーディング

Slide 12

Slide 12 text

エンコーディング ■ 既存のCSVダウンロードの機能はUTF-8で出力している ■ 新規に作るものは Shift-JISで出力してほしいらしい ■ ⇒引数でエンコーディングをとればいんじゃね。汎用性ありそうだし ■ 本日のYAGNIポイントその1 public function build( $items, array $header, string $to = 'SJIS’, string $from = ‘UTF-8’ ): string{/* … */}

Slide 13

Slide 13 text

YAGNIポイント1 ■ そもそもデフォルトの文字コードがUTF-8から外れるようなシステムではない ■ エンコーディング先もShift-JISにするか、そのままのどちらかしか現状は考え られない ■ 考えることがいっぱいありそう – fromとtoが同じ場合でもmb_convert_encoding走らせるの? – 不正な文字コードが来た場合は? ■ ⇒今回のケースでは、「エンコードを変換するか?」だけ指定できれば良かっ たことに気づく

Slide 14

Slide 14 text

YAGNIポイント1 public function build($items, array $header, bool $convert = false): string { $stream = fopen('php://temp', 'w'); fputcsv($stream, $header); foreach ($items as $item) { fputcsv($stream, $item->toCsvRow()); } rewind($stream); $contents = stream_get_contents($stream); if ($convert) { return mb_convert_encoding($contents, 'SJIS', 'UTF-8'); } return $contents; }

Slide 15

Slide 15 text

ヘッダー

Slide 16

Slide 16 text

ヘッダー ■ 今回は人がエクセルで読むようなCSVを作る ■ 機械が読む場合、ヘッダー(タイトル)行は不要な場合は多い ■ どちらにも対応できるように、ヘッダーは設定なしにできるほうがいいのか? public function build($items, array $header = [], bool $convert = false): string { // ... if (count($header) > 0) { fputcsv($stream, $header); } // ... }

Slide 17

Slide 17 text

YAGNIポイント2 ■ 作ったところでいったいいつ使われるのか・・・ ■ 保守性が下がる – 「機械が読めるように処理が工夫されている」 – ⇒「このCSVで外部連携されてる可能性が高い」 – ⇒「変更するなら調査せねば」 – ⇒「・・・外部連携されてないじゃないか!」 ■ 今回のケースでは、コードの修正なし

Slide 18

Slide 18 text

まとめ

Slide 19

Slide 19 text

YAGNIとは ■ “You ain’t gonna need it” ■ (どうせ要らないって!) ■ つまり、実装のコスト支払いをできる限り遅らせる取り組み ■ XPのスローガンの「なんとか動いて、最も無駄のないものを作れ」を支えるプ ラクティスのひとつ

Slide 20

Slide 20 text

YAGNIをするとどうなるか ■ 無駄な抽象度がなくなる – コードが限定的になり読みやすくなる ■ ユニットテストがシンプルになる ■ コード量が無駄に増えない – “コードをできるだけ小さく軽量に維持すること”(リーダブルコード)

Slide 21

Slide 21 text

YAGNIポイント ■ 以下のようなものを作ろうとしたときには「本当に必要?」と自問しよう – フレームワーク – 再利用可能なコンポーネント – フレキシブルな設計 ■ エンジニアはキラキラした言葉に踊らされやすい ■ パターンが使えるときも注意 – 必要ないのにコンストラクタインジェクションしてるコードはよく見かけ る ■ ⇒本当に価値のあるものを作ろう