Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

    View Slide

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



    What is it?

    View Slide

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

    ↓

    しかし目の前にはハウルの動く城

    What is it?

    View Slide

  4. よし!!フルリプレースだ!!



    What is it?

    View Slide

  5. よし!!フルリプレースだ!!

    ↓

    終わらないバベルの塔…

    What is it?

    View Slide

  6. なぜ、リリースが怖くなるのか


    なぜ、リリースが終わらないのか

    What is it?

    View Slide

  7. 「リリースを積み重ねる」を


    実現するために必要な話をします

    What is it?

    View Slide

  8. 1. 自己紹介

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

    3. 小さくリリースする

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

    5. 価値を提供する

    6. まとめ

    あじぇんだ

    View Slide

  9. 1. 自己紹介

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

    3. 小さくリリースする

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

    5. 価値を提供する

    6. まとめ

    あじぇんだ

    View Slide

  10. 自己紹介

    曽根 壮大(38歳)

    Have Fun Tech LLC 代表社員

    株式会社リンケージ CTO


    そ  ね   たけ とも

    ● 日本PostgreSQLユーザ会 勉強会分科会 担当

    ● 3人の子供がいます(長女、次女、長男)

    ● 技術的にはWeb/LL言語/RDBMSが好きです

    ● コミュニティが好き

    View Slide

  11. 1. 自己紹介

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

    3. 小さくリリースする

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

    5. 価値を提供する

    6. まとめ

    あじぇんだ

    View Slide

  12. プロダクトに影響を与える


    リリースをしていますか?

    プロダクトと向き合う

    View Slide

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

    View Slide

  14. リリースされていないコードは


    すべて在庫

    プロダクトと向き合う

    View Slide

  15. “「いい質問だ。定義が『売上』となっているのは、必ず『納品』までを考慮しな
    ければならないためだよ。 仕掛品や完成品の在庫をどれだけ作っても、『納
    品できなければマネジメントが成功したとは言えない』からね」

    確かにそうだ。だが、耳慣れない言葉に、私は思わず聞いていた。「在庫と
    は?この業界に在庫なんてありませんが?」

    私の言葉に、ジョナサンは悲しそうに首を振る。そして言った。

    「いいや、在庫の山はあるのだよ。残念なことに、それこそ山のようにあるだ
    ろう。ものづくりをしている業界で、納期遅れが起きている職場で、現場に在
    庫が無いなどと考えるのは大きな誤りだ」

    「『在庫』とは、将来納品するために存在する、作りかけの未完成品や納品
    前の完成品のことだ。 そのままでは納品できないもの、全てが在庫だ。

    例えばIT業界での『在庫』とは、『書きかけのコード』『未テストのコード』『別の
    コードの完成を待っているテスト済みのコード』 『完成していても顧客に納品
    されていないコード』を指す。もちろん、『完成していても顧客に納品されてい
    ないドキュメント』も在庫だ」”

    https://gist.github.com/voluntas/9c1d9d51e86a853fed6889f743a12145

    View Slide

  16. 成果は


    リリースしたかどうか

    プロダクトと向き合う

    View Slide

  17. タスクは


    未完了 or 完了

    プロダクトと向き合う

    View Slide

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


    View Slide

  19. リリースすれば良い


    ってもんでもない

    プロダクトと向き合う

    View Slide

  20. View Slide

  21. https://soudai.hatenablog.com/entry/2020/08/14/101657
    “例えばリリース手順書を作りました!ってな
    ると作業の内容が変更になるたびに手順書
    のメンテナンスをしなければいけない。そうす
    ると作業が増えるのでリリース方法をできる
    だけ変更したくないという力学が働きやすくな
    る。

     その結果、自分たちがリリース方法を変え
    るだけでより良くしていける可能性があっても
    無駄な議論が増えたり、間接的な作業がま
    た増えたりする。

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


    View Slide

  22. つまり、タスクを積み重ねて


    大きなアウトカムを生むことが大事

    プロダクトと向き合う

    View Slide

  23. つまり、タスクを積み重ねて


    大きなアウトカムを生むことが大事

    プロダクトと向き合う
    意味のないタスクをいくら積み重ねても意味が無い 


    View Slide

  24. アウトカムを生む



    プロダクトと向き合う

    View Slide

  25. アウトカムを生む

    ↓

    サービスの成長を止めない

    プロダクトと向き合う

    View Slide

  26. “リファクタリングできてますか?

    ● サービス開発が優先…

    ● 技術的負債の返済に理解が無い…

    ● どこからやればいいかわからない…

     これは全部言い訳です。”

    https://speakerdeck.com/soudai/web-refactoring

    View Slide

  27. サービスの


    稼働と進化を止めない

    プロダクトと向き合う

    View Slide

  28. フルリプレースは


    多くの場合、サービスの進化を止める

    プロダクトと向き合う

    View Slide

  29. フルリプレース、そのものは


    価値をうまない

    プロダクトと向き合う

    View Slide

  30. フルリプレース、そのものは


    価値をうまない

    プロダクトと向き合う
    リリースサイクルの改善や機能開発のアウトカムによって価値が生まれる 

    リプレースはゴールではない 


    View Slide

  31. 眼の前のコードに


    不満をぶつけても解決はしない

    プロダクトと向き合う

    View Slide

  32. 眼の前のコードに


    不満をぶつけても解決はしない

    プロダクトと向き合う
    改善するためには手を動かしてリリースするしかない 

    それは自分たちしかできないこと 


    View Slide

  33. “例えば使っているOSSにバグがあった
    らどうだろう?これは自戒をかなり含む
    が不満をSNSで書き散らかし、コード側
    には場当たり的な追加をしてないだろう
    か。

     我々はソフトウェアエンジニアだしOSS
    は公開されているので問題があるなら
    パッチを送ればいいし、不満があるなら
    要望を出せば良い。

     愚痴はTwitterに書いても作者に届か
    ないし、場当たり的なコードを書いても根
    本的な問題は解決しない。”

    https://soudai.hatenablog.com/entry/2018/02/09/131638

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  38. レガシィコードに向き合う意味



    プロダクトと向き合う

    View Slide

  39. レガシィコードに向き合う意味

    ↓

    使われているコードは価値がある

    プロダクトと向き合う

    View Slide

  40. レガシィコードの改善は


    直接的な価値の向上につながる

    プロダクトと向き合う

    View Slide



  41. “手を動かした者だけが、世界を変える”




    株式会社はてな id:onishi

    前に進むために必要なこと

    View Slide

  42. 1. 自己紹介

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

    3. 小さくリリースする

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

    5. 価値を提供する

    6. まとめ

    あじぇんだ

    View Slide

  43. リリースはしたい、しかし難しい


    これを乗り越えていく

    小さくリリースする

    View Slide

  44. スコープは小さく


    リリースは素早く

    小さくリリースする

    View Slide

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

    View Slide

  46. Small is beautiful.


    小さいものは美しい

    小さくリリースする

    View Slide

  47. Small is beautiful.
    小さなプログラムという発想
    1. 小さなプログラムはわかりやすい
    2. 小さなプログラムは保守しやすい
    3. 小さなプログラムはシステム
    リソースに優しい
    4. 小さなプログラムは他のツールと組
    み合わせやすい
    https://amzn.to/33QPAdv

    View Slide

  48. Make each program do one thing well.


    1つのプログラムには

    1つのことをうまくやらせる

    小さくリリースする

    View Slide

  49. Make each program do
    one thing well.
    一つのことに集中することで
    プログラムに不要な部分をなくせる。
    不要な部分があると、
    実行速度が遅くなり、
    不必要に複雑になり、
    融通が効かない。
    https://amzn.to/33QPAdv

    View Slide

  50. Build a prototype as soon as possible.


    できるだけ早く試作する

    小さくリリースする

    View Slide

  51. Build a prototype as
    soon as possible.
    ソフトウェアには常に改善の余地はあるの
    はもちろんだし、時間的な制約などでその
    ソースコードは必ずしも最高の状態が保た
    れているわけではない。
    ほとんどのソフトウェアは妥協の産物だ。
    完成することはなく、ただリリースがあるだ
    けだ。
    https://amzn.to/33QPAdv

    View Slide

  52. Build a prototype as
    soon as possible.
    UNIXの考え方では、なるべくはやく第三のシス
    テムを構築するために、すばやく試作
    することをおすすめしている。
    直接、第三のシステムをつくることは
    できないのだ。
    1. 短い機能仕様書を書く (3〜4枚程度)
    2. ソフトウェアを書く
    3. テストして書き直す。
    満足できるまで、これを繰り返す。
    4. 詳細なドキュメントを (必要なら)書く
    https://amzn.to/33QPAdv

    View Slide

  53. Unixの哲学を


    どうやって実現するか

    小さくリリースする

    View Slide

  54. 小さくリリースする



    小さくリリースする

    View Slide

  55. 小さくリリースする

    ↓

    例えば、段階的リリース

    小さくリリースする
    例えばFeature Toggles 


    View Slide

  56. $view_flag = $_GET[‘v’];
    ?>


    サンプル


    PHPのテストです。
    = $view_flag ? $view : null ?>


    https://hoge.com?v=true
    特定のフラグのときだけ、特定
    の表示する
    1. ボタン
    2. リンク
    3. バナー
    4. コンポーネント
    5. 画面
    6. 機能
    Viewを見せない

    View Slide

  57. 全てを同時にリリースしない



    小さくリリースする

    View Slide

  58. 全てを同時にリリースしない

    ↓

    影響範囲を分割する

    小さくリリースする

    View Slide

  59. 常にロールバックを出来る



    小さくリリースする

    View Slide

  60. 影響範囲を分割する

    ● データベースの変更だけ行う

    ○ テーブル・カラム追加とコードのリリースを分ける

    ● CSSやJSなどの静的ファイルを先にリリースする

    ● フロントとバックエンドのリリースを分ける ...etc

    小さくリリースする

    View Slide

  61. 影響範囲を分割する

    ● ALBでリリース対象をロードバランシングする

    ● DNSで切り替える

    ○ pre.host.name → prod.host.name

    ● 参照するデータを分ける

    小さくリリースする

    View Slide

  62. スコープは小さく


    新たな複雑を導入しない

    小さくリリースする

    View Slide

  63. シンプルと


    イージーは違う

    小さくリリースする

    View Slide

  64. 小さくリリースする

    View Slide

  65. 常にロールバックを出来る



    小さくリリースする

    View Slide

  66. 常にロールバックを出来る

    ↓

    リリースを恐れなくて良い

    小さくリリースする

    View Slide

  67. 仕事の進め方も一緒



    小さくリリースする

    View Slide

  68. “やりたいことを実現するために必
    要なことは、そんなに難しいことじゃ
    なくて以下の条件を満たし、実行す
    ることが大事だ。

    ● やりたいこと=課題をタスクに分
    解する

    ● タスクを実行できるだけのリソー
    ス(時間・お金・体力など)を割り
    当てる

    ● 実行する

     これだけなんだ。”

    https://soudai.hatenablog.com/entry/2020/12/31/165940

    View Slide

  69. 細かい分解の話は


    上のスライドと記事を読んでください

    小さくリリースする

    View Slide

  70. 1. 自己紹介

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

    3. 小さくリリースする

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

    5. 価値を提供する

    6. まとめ

    あじぇんだ

    View Slide

  71. 突然ですがソフトウェアは壊れるし、


    ソフトウェアには寿命があります

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

    View Slide

  72. ソフトウェアの寿命



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

    View Slide

  73. ソフトウェアの寿命

    ↓

    リプレースの機運

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

    View Slide

  74. ソフトウェアの寿命を


    伸ばすために必要なこと

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

    View Slide

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

    View Slide

  76. 遊びと余裕



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

    View Slide

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

    View Slide

  78. コードの遊び



    コードの遊びと余裕

    View Slide

  79. コードの遊び

    ↓

    コードの変更(膨張)を受け入れる場所

    コードの遊びと余裕

    View Slide

  80. Decoratorパターン



    コードの遊びと余裕

    View Slide

  81. Decoratorパターン



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

    View Slide

  82. Decoratorパターン


    http://shimooka.hateblo.jp/entry/20141217/1418788239
    コードの遊びと余裕

    View Slide

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

    View Slide

  84. 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パターン

    View Slide

  85. /**
    * テキストを扱うインターフェースクラスです
    */
    interface Text {
    public function getText();
    public function setText($str);
    }
    Decoratorパターンの場合。
    まずはインターフェイスを定義
    する。
    Decoratorパターン

    View Slide

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

    View Slide

  87. 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パターン

    View Slide

  88. 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パターン

    View Slide

  89. 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パターン

    View Slide

  90. $text_object = new PlainText();
    $text_object->setText($text);
    $double_text_object = new DoubleByteText($text_object);
    $double_text_object->getText();
    使い方
    Decoratorパターン

    View Slide

  91. コードの遊びから生まれる余裕

    ● 遠回りをしているように見えるが結果はシンプル

    ○ シンプルとイージーは違う

    ● 影響範囲、スコープを極小化できる

    ● シンプルが機能追加のためのコードに余裕を与える

    コードの遊びと余裕

    View Slide

  92. 他にも色んなテクニックがある


    知識と経験が『知恵』を生む

    コードの遊びと余裕

    View Slide

  93. 他にも色んなテクニックがある


    知識と経験が『知恵』を生む

    コードの遊びと余裕
    デザインパターンや、SOLIDの原則を学ぶ理由はここにある

    View Slide

  94. ソフトウェアの寿命を


    伸ばすために必要なこと

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

    View Slide

  95. データベース設計も同じ



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

    View Slide

  96. 正規化とSimple is beautiful

     ここまでシンプルな実装を目指しましょうと強調してきましたが、「シンプ
    ルな実装」とはなんでしょうか。RDBMSを使う上でシンプルな実装のヒン
    トは正規化です。正規化のコツは次のように表現できます。

    ● 事実だけを保存する

    ● 重複がない

    ● 不整合がない

    ● nullがない

    (中略)

     このようにシンプルな設計を目指して考察を繰り返していくことが重要
    です。そして同じくらい重要なこととして認識すべきはイージーとシンプル
    は両立できる、ということです。シンプルを目指し考察を繰り返すことがま
    さにデータモデリングであり、変化に強い設計につながっていくのです。


    https://agilejourney.uzabase.com/entry/2022/07/28/103000

    View Slide

  97. 変更に強い設計は


    ソフトウェアの寿命を伸ばす

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

    View Slide

  98. ソフトウェアの寿命は


    ビジネスインパクトがある

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

    View Slide

  99. 1. 自己紹介

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

    3. 小さくリリースする

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

    5. 価値を提供する

    6. まとめ

    あじぇんだ

    View Slide

  100. 良い開発、良いチームとは


    どんなチームを想像しますか?

    価値を提供する

    View Slide

  101. 目的を達成できるのが良い開発


    目的を達成できるチームが良いチーム

    価値を提供する

    View Slide

  102. 我々の目的は


    ユーザに価値を届けること

    価値を提供する

    View Slide

  103. 目指すべきチーム

    ↓

    良い価値を提供できるチーム

    価値を提供する

    View Slide

  104. 良い価値とはなにか?



    価値を提供する

    View Slide

  105. 良い価値とはなにか?

    ↓

    提供してみないとわからない

    価値を提供する

    View Slide

  106. だから最初に


    サービスのリリースが必要

    価値を提供する

    View Slide

  107. 1. ユーザが使ってくれてはじめて価値がある(再掲)

    答えは常に市場が知っている

    ユーザのフィードバックを正しく観測して次の課題を見つける

    机上の空論は価値を届けていない

    2. 完璧は幻想であり、完成はない

    我々も形にならないと想像できない、作ってみないと想像できない

    考えることよりも、実際に作ってみて、小さく失敗する

    失敗を素早く次に活かして、次は上手くやる

    3. 失敗と改善のサイクルを高速に回す

    進化の反対は退化(機能削減)ではなく、停滞。

    なぜリリースが必要か

    View Slide

  108. より良い価値を継続的に届けるために


    失敗を沢山できる仕組みにする

    価値を提供する

    View Slide

  109. 1. 大きく失敗しない

    失敗は小さく、変化も小さくすることで失敗の範囲を最小にする

    アプリケーションの影響範囲もできるだけ小さくリリースする

    2. 素早く元に戻せる

    素早くリリースできれば、素早くロールバックできる

    やり直せるならチャレンジのハードルが下がる

    チャレンジの数だけ、学びが生まれる

    3. 問題に素早く気付く

    問題に素早く気付くことができれば、素早く改善することができる

    改善することでよりよい価値を提供できる

    失敗するために必要な仕組み

    View Slide

  110. 失敗できる仕組みとプロセス

    ↓

    良い開発につながる

    価値を提供する
    CI/CDもTDDもDevOpsもマイクロサービスもDDDも 

    結局はここを実現するためのhow(手段) 


    View Slide

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


    View Slide

  112. 失敗を許容する

    ● ログを元に再実行できる

    ○ 冪等性

    ● ログを元にデータを再現できる

    ○ 再現性

    ● ログを元にどこまで・何が・どうなったかわかる

    ○ 可観測性

    ログとリトライとリラン

    View Slide

  113. 失敗を許容する

    ● ログを元に再実行できる

    ○ 冪等性

    ● ログを元にデータを再現できる

    ○ 再現性

    ● ログを元にどこまで・何が・どうなったかわかる

    ○ 可観測性

    ログとリトライとリラン
    例えばエラーログが出たときに「次はこのコマンドを叩いてくれ」とメッセージ
    を出すことができるか? 


    View Slide

  114. 良い開発、良いチームとはなにか



    価値を提供する

    View Slide

  115. 素早く価値を提供できていて


    失敗と改善が可能なチーム

    価値を提供する

    View Slide

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



    価値を提供する

    View Slide

  117. 1. 自己紹介

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

    3. 小さくリリースする

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

    5. 価値を提供する

    6. まとめ

    あじぇんだ

    View Slide

  118. まとめ

    View Slide

  119. 目の前のコードを直すことができるのは


    自分たちだけ

    まとめ

    View Slide

  120. 価値のあるコードを生み出すことが


    ソフトウェアエンジニアの価値

    まとめ

    View Slide

  121. 価値のあるコードを直したことがある


    という経験がキャリアを生む

    まとめ

    View Slide

  122. 知っているとできるは違う


    できることで成果が決まる

    まとめ

    View Slide

  123. 知る

    (知識の壁)

    やる

    (行動の壁)

    わかる

    (理解の壁)

    できる

    (技術の壁)

    している

    (習慣の壁)

    ステップアップしていくことが大切

    知らない

    (無知の知)

    まとめ

    View Slide

  124. 技術で問題解決をしましょう



    まとめ

    View Slide

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



    まとめ

    View Slide