$30 off During Our Annual Pro Sale. View Details »

プロダクトと向き合いながら 目の前のコードと戦うには / Fight the code in front of you

soudai sone
November 02, 2022

プロダクトと向き合いながら 目の前のコードと戦うには / Fight the code in front of you

コドモン社でのセミナー内容です

soudai sone

November 02, 2022
Tweet

More Decks by soudai sone

Other Decks in Technology

Transcript

  1. プロダクトと向き合いながら 目の前のコードと戦うには ~ 進捗を出すために必要なリリース方法について ~ 株式会社コドモン 開発研修

  2. プロダクトと向き合う
 
 
 What is it?

  3. プロダクトと向き合う
 ↓
 しかし目の前にはハウルの動く城
 What is it?

  4. よし!!フルリプレースだ!!
 
 
 What is it?

  5. よし!!フルリプレースだ!!
 ↓
 終わらないバベルの塔…
 What is it?

  6. なぜ、リリースが怖くなるのか
 
 なぜ、リリースが終わらないのか
 What is it?

  7. 「リリースを積み重ねる」を
 
 実現するために必要な話をします
 What is it?

  8. 1. 自己紹介
 2. プロダクトと向き合う
 3. 小さくリリースする
 4. 壊さない設計とソフトウェアの寿命
 5. 価値を提供する


    6. まとめ
 あじぇんだ
  9. 1. 自己紹介
 2. プロダクトと向き合う
 3. 小さくリリースする
 4. 壊さない設計とソフトウェアの寿命
 5. 価値を提供する


    6. まとめ
 あじぇんだ
  10. 自己紹介
 曽根 壮大(38歳)
 Have Fun Tech LLC 代表社員
 株式会社リンケージ CTO


    
 そ  ね   たけ とも
 • 日本PostgreSQLユーザ会 勉強会分科会 担当
 • 3人の子供がいます(長女、次女、長男)
 • 技術的にはWeb/LL言語/RDBMSが好きです
 • コミュニティが好き
  11. 1. 自己紹介
 2. プロダクトと向き合う
 3. 小さくリリースする
 4. 壊さない設計とソフトウェアの寿命
 5. 価値を提供する


    6. まとめ
 あじぇんだ
  12. プロダクトに影響を与える
 
 リリースをしていますか?
 プロダクトと向き合う

  13. プロダクトと向き合う https://speakerdeck.com/soudai/necessary-mindset-for-software-developers

  14. リリースされていないコードは
 
 すべて在庫
 プロダクトと向き合う

  15. “「いい質問だ。定義が『売上』となっているのは、必ず『納品』までを考慮しな ければならないためだよ。 仕掛品や完成品の在庫をどれだけ作っても、『納 品できなければマネジメントが成功したとは言えない』からね」
 確かにそうだ。だが、耳慣れない言葉に、私は思わず聞いていた。「在庫と は?この業界に在庫なんてありませんが?」
 私の言葉に、ジョナサンは悲しそうに首を振る。そして言った。
 「いいや、在庫の山はあるのだよ。残念なことに、それこそ山のようにあるだ ろう。ものづくりをしている業界で、納期遅れが起きている職場で、現場に在 庫が無いなどと考えるのは大きな誤りだ」


    「『在庫』とは、将来納品するために存在する、作りかけの未完成品や納品 前の完成品のことだ。 そのままでは納品できないもの、全てが在庫だ。
 例えばIT業界での『在庫』とは、『書きかけのコード』『未テストのコード』『別の コードの完成を待っているテスト済みのコード』 『完成していても顧客に納品 されていないコード』を指す。もちろん、『完成していても顧客に納品されてい ないドキュメント』も在庫だ」”
 https://gist.github.com/voluntas/9c1d9d51e86a853fed6889f743a12145
  16. 成果は
 
 リリースしたかどうか
 プロダクトと向き合う

  17. タスクは
 
 未完了 or 完了
 プロダクトと向き合う

  18. プロダクトと向き合う 実装 テスト バグ対応 未完成 完了 リリースの壁


  19. リリースすれば良い
 
 ってもんでもない
 プロダクトと向き合う

  20. None
  21. https://soudai.hatenablog.com/entry/2020/08/14/101657 “例えばリリース手順書を作りました!ってな ると作業の内容が変更になるたびに手順書 のメンテナンスをしなければいけない。そうす ると作業が増えるのでリリース方法をできる だけ変更したくないという力学が働きやすくな る。
  その結果、自分たちがリリース方法を変え るだけでより良くしていける可能性があっても 無駄な議論が増えたり、間接的な作業がま

    た増えたりする。
  こうやって作業が増え、仕事が増え、リソー スがどんどん足りなくなる ”

  22. つまり、タスクを積み重ねて
 
 大きなアウトカムを生むことが大事
 プロダクトと向き合う

  23. つまり、タスクを積み重ねて
 
 大きなアウトカムを生むことが大事
 プロダクトと向き合う 意味のないタスクをいくら積み重ねても意味が無い 


  24. アウトカムを生む
 
 
 プロダクトと向き合う

  25. アウトカムを生む
 ↓
 サービスの成長を止めない
 プロダクトと向き合う

  26. “リファクタリングできてますか? 
 • サービス開発が優先…
 • 技術的負債の返済に理解が無い…
 • どこからやればいいかわからない…
  これは全部言い訳です。”
 https://speakerdeck.com/soudai/web-refactoring

  27. サービスの
 
 稼働と進化を止めない
 プロダクトと向き合う

  28. フルリプレースは
 
 多くの場合、サービスの進化を止める
 プロダクトと向き合う

  29. フルリプレース、そのものは
 
 価値をうまない
 プロダクトと向き合う

  30. フルリプレース、そのものは
 
 価値をうまない
 プロダクトと向き合う リリースサイクルの改善や機能開発のアウトカムによって価値が生まれる 
 リプレースはゴールではない 


  31. 眼の前のコードに
 
 不満をぶつけても解決はしない
 プロダクトと向き合う

  32. 眼の前のコードに
 
 不満をぶつけても解決はしない
 プロダクトと向き合う 改善するためには手を動かしてリリースするしかない 
 それは自分たちしかできないこと 


  33. “例えば使っているOSSにバグがあった らどうだろう?これは自戒をかなり含む が不満をSNSで書き散らかし、コード側 には場当たり的な追加をしてないだろう か。
  我々はソフトウェアエンジニアだしOSS は公開されているので問題があるなら パッチを送ればいいし、不満があるなら 要望を出せば良い。
  愚痴はTwitterに書いても作者に届か

    ないし、場当たり的なコードを書いても根 本的な問題は解決しない。”
 https://soudai.hatenablog.com/entry/2018/02/09/131638
  34. プロダクトと向き合う

  35. プロダクトと向き合う

  36. プロダクトと向き合う

  37. プロダクトと向き合う

  38. レガシィコードに向き合う意味
 
 
 プロダクトと向き合う

  39. レガシィコードに向き合う意味
 ↓
 使われているコードは価値がある
 プロダクトと向き合う

  40. レガシィコードの改善は
 
 直接的な価値の向上につながる
 プロダクトと向き合う

  41. 
 
 “手を動かした者だけが、世界を変える”
 
 
 
 株式会社はてな id:onishi
 前に進むために必要なこと

  42. 1. 自己紹介
 2. プロダクトと向き合う
 3. 小さくリリースする
 4. 壊さない設計とソフトウェアの寿命
 5. 価値を提供する


    6. まとめ
 あじぇんだ
  43. リリースはしたい、しかし難しい
 
 これを乗り越えていく
 小さくリリースする

  44. スコープは小さく
 
 リリースは素早く
 小さくリリースする

  45. 小さくリリースする https://speakerdeck.com/soudai/release-safely-2

  46. Small is beautiful.
 
 小さいものは美しい
 小さくリリースする

  47. Small is beautiful. 小さなプログラムという発想 1. 小さなプログラムはわかりやすい 2. 小さなプログラムは保守しやすい 3. 小さなプログラムはシステム

    リソースに優しい 4. 小さなプログラムは他のツールと組 み合わせやすい https://amzn.to/33QPAdv
  48. Make each program do one thing well.
 
 1つのプログラムには
 1つのことをうまくやらせる


    小さくリリースする
  49. Make each program do one thing well. 一つのことに集中することで プログラムに不要な部分をなくせる。 不要な部分があると、

    実行速度が遅くなり、 不必要に複雑になり、 融通が効かない。 https://amzn.to/33QPAdv
  50. Build a prototype as soon as possible.
 
 できるだけ早く試作する
 小さくリリースする

  51. Build a prototype as soon as possible. ソフトウェアには常に改善の余地はあるの はもちろんだし、時間的な制約などでその ソースコードは必ずしも最高の状態が保た

    れているわけではない。 ほとんどのソフトウェアは妥協の産物だ。 完成することはなく、ただリリースがあるだ けだ。 https://amzn.to/33QPAdv
  52. Build a prototype as soon as possible. UNIXの考え方では、なるべくはやく第三のシス テムを構築するために、すばやく試作 することをおすすめしている。

    直接、第三のシステムをつくることは できないのだ。 1. 短い機能仕様書を書く (3〜4枚程度) 2. ソフトウェアを書く 3. テストして書き直す。 満足できるまで、これを繰り返す。 4. 詳細なドキュメントを (必要なら)書く https://amzn.to/33QPAdv
  53. Unixの哲学を
 
 どうやって実現するか
 小さくリリースする

  54. 小さくリリースする
 
 
 小さくリリースする

  55. 小さくリリースする
 ↓
 例えば、段階的リリース
 小さくリリースする 例えばFeature Toggles 


  56. <?php $view_flag = $_GET[‘v’]; ?> <html> <head> <title>サンプル</title> </head> <body>

    <p>PHPのテストです。</p> <?= $view_flag ? $view : null ?> </body> </html> https://hoge.com?v=true 特定のフラグのときだけ、特定 の表示する 1. ボタン 2. リンク 3. バナー 4. コンポーネント 5. 画面 6. 機能 Viewを見せない
  57. 全てを同時にリリースしない
 
 
 小さくリリースする

  58. 全てを同時にリリースしない
 ↓
 影響範囲を分割する
 小さくリリースする

  59. 常にロールバックを出来る
 
 
 小さくリリースする

  60. 影響範囲を分割する
 • データベースの変更だけ行う
 ◦ テーブル・カラム追加とコードのリリースを分ける
 • CSSやJSなどの静的ファイルを先にリリースする
 • フロントとバックエンドのリリースを分ける ...etc


    小さくリリースする
  61. 影響範囲を分割する
 • ALBでリリース対象をロードバランシングする
 • DNSで切り替える
 ◦ pre.host.name → prod.host.name
 •

    参照するデータを分ける
 小さくリリースする
  62. スコープは小さく
 
 新たな複雑を導入しない
 小さくリリースする

  63. シンプルと
 
 イージーは違う
 小さくリリースする

  64. 小さくリリースする

  65. 常にロールバックを出来る
 
 
 小さくリリースする

  66. 常にロールバックを出来る
 ↓
 リリースを恐れなくて良い
 小さくリリースする

  67. 仕事の進め方も一緒
 
 
 小さくリリースする

  68. “やりたいことを実現するために必 要なことは、そんなに難しいことじゃ なくて以下の条件を満たし、実行す ることが大事だ。
 • やりたいこと=課題をタスクに分 解する
 • タスクを実行できるだけのリソー ス(時間・お金・体力など)を割り

    当てる
 • 実行する
  これだけなんだ。”
 https://soudai.hatenablog.com/entry/2020/12/31/165940
  69. 細かい分解の話は
 
 上のスライドと記事を読んでください
 小さくリリースする

  70. 1. 自己紹介
 2. プロダクトと向き合う
 3. 小さくリリースする
 4. 壊さない設計とソフトウェアの寿命
 5. 価値を提供する


    6. まとめ
 あじぇんだ
  71. 突然ですがソフトウェアは壊れるし、
 
 ソフトウェアには寿命があります
 壊さない設計とソフトウェアの寿命

  72. ソフトウェアの寿命
 
 
 壊さない設計とソフトウェアの寿命

  73. ソフトウェアの寿命
 ↓
 リプレースの機運
 壊さない設計とソフトウェアの寿命

  74. ソフトウェアの寿命を
 
 伸ばすために必要なこと
 壊さない設計とソフトウェアの寿命

  75. 壊さない設計とソフトウェアの寿命 https://speakerdeck.com/soudai/release-safely-2

  76. 遊びと余裕
 
 
 壊さない設計とソフトウェアの寿命

  77. 遊びは仕組み 遊びの仕組みの活用例が右の 図、橋の結合部の隙間。 橋は夏などの気温が高いときに熱 膨張する。このときの熱膨張分の 隙間が最初から用意されている。 wikipedia: 熱膨張から引用

  78. コードの遊び
 
 
 コードの遊びと余裕

  79. コードの遊び
 ↓
 コードの変更(膨張)を受け入れる場所
 コードの遊びと余裕

  80. Decoratorパターン
 
 
 コードの遊びと余裕

  81. Decoratorパターン
 
 
 コードの遊びと余裕 継承ではなく、委譲で機能を追加していくパターン。 そーだいさんはDo You PHP で育ったので今日はそこから引用して説明する。 みんな

    @shimooka さんに感謝して読むんだぞ!
  82. Decoratorパターン
 
 http://shimooka.hateblo.jp/entry/20141217/1418788239 コードの遊びと余裕

  83. <?php class PlainText { private $textString = null; public function

    getText() { return $this->textString; } public function setText($str) { $this->textString = $str; } } 文字列を扱うクラス。 これに大文字するメソッドを追 加したい場合は? Decoratorパターン
  84. <?php class PlainText { private $textString = null; public function

    getText() { return $this->textString; } public function setText($str) { $this->textString = $str; } // 現場で一番良く見る実装 public function upperCaseGetText($str) { return mb_strtoupper($this->getText()); } } 仕様追加のたびにPlainTextク ラスが大きくなる。 小文字にしたい場合など、どん どんこのクラスが大きくなって いくことが目に見えている。 getText()にifを追加するのは もっとダメ。 Decoratorパターン
  85. <?php /** * テキストを扱うインターフェースクラスです */ interface Text { public function

    getText(); public function setText($str); } Decoratorパターンの場合。 まずはインターフェイスを定義 する。 Decoratorパターン
  86. <?php class PlainText implements Text { private $textString = null;

    public function getText() { return $this->textString; } public function setText($str) { $this->textString = $str; } } 先程のクラスと一緒。 インターフェイスに対する 実装クラスになった。 Decoratorパターン
  87. <?php require_once('Text.class.php'); abstract class TextDecorator implements Text { private $text;

    public function __construct(Text $target) { $this->text = $target; } public function getText() { return $this->text->getText(); } public function setText($str) { $this->text->setText($str); } } Decoratorクラスを作る。 コードの遊び部分になる。 Decoratorパターン
  88. <?php require_once('TextDecorator.class.php'); class UpperCaseText extends TextDecorator { public function __construct(Text

    $target) { parent::__construct($target); } public function getText() { $str = parent::getText(); $str = mb_strtoupper($str); return $str; } } さぁ!Textをdecorateしてみ ましょう!! UpperCaseTextクラスを実装 するとこうなる。 元のPlainTextクラスに全く影 響を与えずに機能を追加する ことができた。 Decoratorパターン
  89. <?php require_once('TextDecorator.class.php'); class DoubleByteText extends TextDecorator { public function __construct(Text

    $target) { parent::__construct($target); } /** * テキストを全角文字に変換して返します * 半角英字、数字、スペース、カタカナを全角に、 * 濁点付きの文字を一文字に変換します */ public function getText() { $str = parent::getText(); $str = mb_convert_kana($str,"RANSKV"); return $str; } } さらに機能追加。 機能追加の単位がクラスに閉 じるので仕様追加の範囲が絞 ることができる。 1クラス、1責務。 シンプルでわかりやすい。 Decoratorパターン
  90. $text_object = new PlainText(); $text_object->setText($text); $double_text_object = new DoubleByteText($text_object); $double_text_object->getText();

    使い方 Decoratorパターン
  91. コードの遊びから生まれる余裕
 • 遠回りをしているように見えるが結果はシンプル
 ◦ シンプルとイージーは違う
 • 影響範囲、スコープを極小化できる
 • シンプルが機能追加のためのコードに余裕を与える
 コードの遊びと余裕

  92. 他にも色んなテクニックがある
 
 知識と経験が『知恵』を生む
 コードの遊びと余裕

  93. 他にも色んなテクニックがある
 
 知識と経験が『知恵』を生む
 コードの遊びと余裕 デザインパターンや、SOLIDの原則を学ぶ理由はここにある 


  94. ソフトウェアの寿命を
 
 伸ばすために必要なこと
 壊さない設計とソフトウェアの寿命

  95. データベース設計も同じ
 
 
 壊さない設計とソフトウェアの寿命

  96. 正規化とSimple is beautiful
  ここまでシンプルな実装を目指しましょうと強調してきましたが、「シンプ ルな実装」とはなんでしょうか。RDBMSを使う上でシンプルな実装のヒン トは正規化です。正規化のコツは次のように表現できます。
 • 事実だけを保存する
 • 重複がない


    • 不整合がない
 • nullがない
 (中略)
  このようにシンプルな設計を目指して考察を繰り返していくことが重要 です。そして同じくらい重要なこととして認識すべきはイージーとシンプル は両立できる、ということです。シンプルを目指し考察を繰り返すことがま さにデータモデリングであり、変化に強い設計につながっていくのです。
 
 https://agilejourney.uzabase.com/entry/2022/07/28/103000
  97. 変更に強い設計は
 
 ソフトウェアの寿命を伸ばす
 壊さない設計とソフトウェアの寿命

  98. ソフトウェアの寿命は
 
 ビジネスインパクトがある
 壊さない設計とソフトウェアの寿命

  99. 1. 自己紹介
 2. プロダクトと向き合う
 3. 小さくリリースする
 4. 壊さない設計とソフトウェアの寿命
 5. 価値を提供する


    6. まとめ
 あじぇんだ
  100. 良い開発、良いチームとは
 
 どんなチームを想像しますか?
 価値を提供する

  101. 目的を達成できるのが良い開発
 
 目的を達成できるチームが良いチーム
 価値を提供する

  102. 我々の目的は
 
 ユーザに価値を届けること
 価値を提供する

  103. 目指すべきチーム
 ↓
 良い価値を提供できるチーム
 価値を提供する

  104. 良い価値とはなにか?
 
 
 価値を提供する

  105. 良い価値とはなにか?
 ↓
 提供してみないとわからない
 価値を提供する

  106. だから最初に
 
 サービスのリリースが必要
 価値を提供する

  107. 1. ユーザが使ってくれてはじめて価値がある(再掲)
 答えは常に市場が知っている
 ユーザのフィードバックを正しく観測して次の課題を見つける
 机上の空論は価値を届けていない
 2. 完璧は幻想であり、完成はない
 我々も形にならないと想像できない、作ってみないと想像できない
 考えることよりも、実際に作ってみて、小さく失敗する
 失敗を素早く次に活かして、次は上手くやる


    3. 失敗と改善のサイクルを高速に回す
 進化の反対は退化(機能削減)ではなく、停滞。
 なぜリリースが必要か
  108. より良い価値を継続的に届けるために
 
 失敗を沢山できる仕組みにする
 価値を提供する

  109. 1. 大きく失敗しない
 失敗は小さく、変化も小さくすることで失敗の範囲を最小にする
 アプリケーションの影響範囲もできるだけ小さくリリースする
 2. 素早く元に戻せる
 素早くリリースできれば、素早くロールバックできる
 やり直せるならチャレンジのハードルが下がる
 チャレンジの数だけ、学びが生まれる
 3.

    問題に素早く気付く
 問題に素早く気付くことができれば、素早く改善することができる
 改善することでよりよい価値を提供できる
 失敗するために必要な仕組み
  110. 失敗できる仕組みとプロセス
 ↓
 良い開発につながる
 価値を提供する CI/CDもTDDもDevOpsもマイクロサービスもDDDも 
 結局はここを実現するためのhow(手段) 


  111. 失敗できる仕組みの例 当然書いてない


  112. 失敗を許容する
 • ログを元に再実行できる
 ◦ 冪等性
 • ログを元にデータを再現できる
 ◦ 再現性
 •

    ログを元にどこまで・何が・どうなったかわかる
 ◦ 可観測性
 ログとリトライとリラン
  113. 失敗を許容する
 • ログを元に再実行できる
 ◦ 冪等性
 • ログを元にデータを再現できる
 ◦ 再現性
 •

    ログを元にどこまで・何が・どうなったかわかる
 ◦ 可観測性
 ログとリトライとリラン 例えばエラーログが出たときに「次はこのコマンドを叩いてくれ」とメッセージ を出すことができるか? 

  114. 良い開発、良いチームとはなにか
 
 
 価値を提供する

  115. 素早く価値を提供できていて
 
 失敗と改善が可能なチーム
 価値を提供する

  116. 自分たちの手で価値を提供しよう
 
 
 価値を提供する

  117. 1. 自己紹介
 2. プロダクトと向き合う
 3. 小さくリリースする
 4. 壊さない設計とソフトウェアの寿命
 5. 価値を提供する


    6. まとめ
 あじぇんだ
  118. まとめ

  119. 目の前のコードを直すことができるのは
 
 自分たちだけ
 まとめ

  120. 価値のあるコードを生み出すことが
 
 ソフトウェアエンジニアの価値
 まとめ

  121. 価値のあるコードを直したことがある
 
 という経験がキャリアを生む
 まとめ

  122. 知っているとできるは違う
 
 できることで成果が決まる
 まとめ

  123. 知る
 (知識の壁)
 やる
 (行動の壁)
 わかる
 (理解の壁)
 できる
 (技術の壁)
 している
 (習慣の壁)


    ステップアップしていくことが大切
 知らない
 (無知の知)
 まとめ
  124. 技術で問題解決をしましょう
 
 
 まとめ

  125. ご清聴ありがとうございました
 
 
 まとめ