小さく失敗するということ、あるいはプレトタイピング(not プロトタイピング)のススメ


この記事は[Ateam Brides Inc. Advent Calendar 2019](https://qiita.com/advent-calendar/2019/a-t-brides)　2日目の記事です。

# 失敗していますか？

システム開発を生業にしていると、大なり小なり何らかの失敗を繰り返しているのではないでしょうか。
皆さんのチームでは失敗に対してどのような態度で接していますか？
この記事では積極的に正しく失敗する方法を考えていこうと思います。

## 失敗を利用する

失敗する要因とその対処については、以前[試論としてまとめた](https://qiita.com/sho0211/items/62a73da59bae2b9a826a)ので繰り返すことはしません。
今回は失敗することを前提にいろいろなことに取り組みましょう、という話を展開します。

# なぜこれを書いたのか

今、僕の中で空前絶後の[NO FLOP!](https://www.amazon.co.jp/google%C3%97%E3%82%B9%E3%82%BF%E3%83%B3%E3%83%95%E3%82%A9%E3%83%BC%E3%83%89-NO-FLOP-%E5%A4%B1%E6%95%97%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84%E4%BA%BA%E3%81%AE%E5%A4%B1%E6%95%97%E3%81%97%E3%81%AA%E3%81%84%E6%8A%80%E8%A1%93-%E3%82%A2%E3%83%AB%E3%83%99%E3%83%AB%E3%83%88%E3%83%BB%E3%82%B5%E3%83%B4%E3%82%A9%E3%82%A4%E3%82%A2/dp/4763137492)ブームがやってきています。
物事を相談されれば、プレトタイピングを考え、提案しますし、事あるごとに本書を読むように勧めています[^recomend]。

[^recomend]: 今では勧められる方も「またNO FLOP!推しか」と苦笑モノです

LEANやアジャイル、DDD、デザイン思考など、新しいことを始めるときに考えるべき道標は数多く示されていますが、その実践としてはなかなかしっくり来る機会が少ないのではないでしょうか。

プ "レ" トタイピングは、考え方を変えて、あなたの役に立つ情報を素早くかんたんに手に入れるための方法として紹介していることが取り入れやすく、何より非エンジニアにとってもわかりやすいアプローチなので、すべての人におすすめできる内容です[^commercial]。

[^commercial]: ここまで宣伝。インセンティブ何もなし。

そして、プレトタイピングの考え方はエンジニアに最適で、普段から利用していただきたいと強く思うのです。
（以下、語り口調が変わります）

# プロジェクトのx割は失敗する

<img src="https://2.bp.blogspot.com/-lU-M7R_3OxE/Vt_t1RNBagI/AAAAAAAA4pI/tBOWbhVcbVI/s800/business_group_shock.png" height="300">

失敗の定義によりいろいろな調査がされていて、何かを始めることの失敗は[５割](https://tech.nikkeibp.co.jp/atcl/nxt/column/18/00177/022100001/)とも[7割](https://www.zdnet.com/article/study-68-percent-of-it-projects-fail/)とも[9割](https://www.failory.com/blog/startup-failure-rate)とも言われる。
ともかく、あなたの携わっているプロジェクトは失敗することがほぼ運命づけられたようなものなのだ。

## あなたが携わるプロジェクトはすべて初の試みである

[インセプションデッキ](https://www.slideshare.net/TakaoOyobe/5-45195080)を思い出してほしい。
「我々はなぜここにいるのか」という章があり、既存の何かでは提供できない価値を届けるために、あなたはそのプロジェクトに参画しているはずなのだ。
たとえ過去の知見を転用したプロジェクトであろうと、まったく同じものを作ってはいない。

## 初の試みが成功するほど世の中甘くない

周知のようにGoogleは[死屍累々たる失敗](https://gcemetery.co/)を繰り返し、多数のイノベーションを起こした[スティーブ・ジョブズでさえ失敗](https://ja.wikipedia.org/wiki/NeXT)し、ジェフ・ベゾスも[結婚生活に失敗した](https://forbesjapan.com/articles/detail/26480)[^divorce]。
いわんや凡人たる僕が成功を前提に計画を立ててうまくいくわけでもない。

[^divorce]: オチをつけたかっただけです。離婚そのものがネガティブなものとは思っていないし、正しく失敗するという趣旨には合わないものです。不謹慎・不快という感想もあるだろうと考えているので、後日編集するかもしれません。

NO FLOPを要約すると、初の試みが失敗する理由は単純なもので、そのアイデアが正しいターゲットを捉えているか、解決方法として正しいかはやってみないとわからない、ということにある。[^abstract]

[^abstract]: ものすごく乱暴な要約なので、正確には本書をお読みください。

# 意味のある失敗とは（プレトタイピング概論）

新しく物事を始めるときに失敗するなら、挑戦しなければよいのか。そうではない。
我々エイチームは[「今から１００年続く会社にすること」](https://www.a-tm.co.jp/about/philosophy/)という理念のもと、既存のビジネスにしがみついて生き延びようとは考えていない。常に新しい挑戦をし続けなければ、１００年を待たずにエイチームが滅んでしまうだろう。
[アマゾンは倒産するとベゾスが言ったこと](https://forbesjapan.com/articles/detail/24003)はまったくもって正しい。

同時に１００年時代の今、あなたの会社や人生も、今あるビジネスや資産だけでは行き詰まることも想像に難くない。
今の幸せを保つために、より良い幸せを手に入れるために、挑戦することが求められるのは多くの人にとって肌で感じているものではないだろうか。

したがって、失敗するにしても正しく失敗し、その挑戦を意味のあるものにして、最終的な価値を手に入れる・提供することにつなげていくべきである。
そしてプレトタイピングとはそのための手法である。

## 実施することを計測可能にする

<img src="https://1.bp.blogspot.com/-3F9wy4hC8Cg/V4SBAiSBvXI/AAAAAAAA8P4/3GflV9xU9RUdIS51ncXuierqcGnIHhWlgCLcB/s800/medical_treadmill_undoufuka_kensa.png" height="300">

今実行しようとしていることを、どのような成果・効果を生むものだと考えているだろうか。
それは定量的に示せる指標を持っているだろうか。
まずは計測可能にしなければ、失敗したことにすら気づけない。

## すぐに失敗する

計測可能になったら、すぐに失敗できることを見つけよう。
どうせそのプロジェクトは失敗する。
念入りに計画を立てても、失敗の可能性はそれほど低くならない。
であれば、作り込む前にそのアイデアをテストするべきだ。
今すぐ実行に移して、そのアイデアの是非を問える方法を見つけよう。

## テストの対象にはコストを払わせる

試供品の頒布など、テストマーケティングといえば無償でのものが思い浮かぶかもしれない。
しかし、プレトタイピングが推奨するのはテスト対象も何らかのコストを払うべきであるということだ。
なぜなら、コストを払う人こそが本来のターゲットであるからだ。
そしてコストを支払ったという思いがあるからこそ、正しいフィードバックが戻ってくるものだ。

## 失敗を分析する

実際にテストをしたあとで、定量化した目論見を達成できていただろうか。
何らかの想定がずれているかもしれない。
うまくいくのであれば、その運用はそのまま進められそうだろうか。
ともかく、定量化したことで、テストを評価することができているはずなのだ。

# システム開発におけるプレトタイピング

さて、ここまではプレトタイピングの概要であった。
システム開発で、かつQiita読者であるITエンジニアたちにとって、プレトタイピングがいかに役立つのかを考えてみてほしい。

## プロジェクトにNOを突きつける

<img src="https://1.bp.blogspot.com/-mS7uHv_yT8Q/V9ppx_usZBI/AAAAAAAA9yA/FCk1Od44CD8aO0FZ9WAeM5PQ4v5oVuz0QCLcB/s800/pet_sanpo_iyagaru_dog.png" height="300">

思慮深いITエンジニア諸氏は、プロジェクトへジョインしたときに「これは絶対にコケる」と思ったことがないだろうか。
そのときに取りうる行動は複数あるが、振り返りの中で「だから言ったのに」と言っても遅い。プロジェクトがコケたのは自分の責任でもあるのだ。

ではどうするのか。
プロジェクトの目的と解決しようとしているものが、本当に正しいのかを一緒に見極めようではないか。
nヶ月、m年の歳月を使って作り上げるのではなく、まずはプロジェクトの方向性を確かめるべきなのだ。
そのときにエンジニアがプレトタイピングを知っていることは大いに意味がある。
なぜなら、実際にものづくりをするあなた達エンジニアが、最後の砦なのだから。
それまでいろいろな人が関わり、プロジェクトとして形を作ってきただろうが、ものづくりをし始める前に立ち止まることができるのは、あなたの判断が最終なのだ。
プレトタイピングを学び、プロジェクトを正しく、小さく失敗を繰り返そうと叫ぶのだ。

そして、ターゲットとソリューションを把握したら、MVP(Minimum Viable Product)を作り始めよう。
良いだろうか。
プレトタイピングを実行するには、**MVPですら作り過ぎ**だと思ってみよう[^mvp]。

[^mvp]: 実際にはLEANの文脈でMVPと呼ぶのはプレトタイプと同等のものを指して良いと考えられるが、`Product`に引きづられて、なにか動くものを作りがちになってしまう。

## アーキテクチャ設計を確認する

昨今では純粋なWeb３層構成でサービスを展開することは稀だろう。
マイクロサービスを作るほどではないにせよ、便利なクラウドサービスを組み合わせて、プロダクト構築をEasyにしていることだろうと想像している。
その時、理屈上では「この構成でいける」ができるだろうが、実際にローンチすると[ネットワークや権限問題](https://www.slideshare.net/AmazonWebServicesJapan/20150609-antipattern-49198289)、そもそもの[サービス境界](https://www.techscore.com/blog/2018/11/12/microservice-architecture-style/)などで失敗するケースが多いだろう。

ここでプレトタイピングしてみよう。

**仮説：正しいアーキテクチャであれば少なくとも95%のリクエストは、ステータス200での結果が返ってくる**


行動としてはこのようなことができそうだ。

- 実際にものを作ることが簡単なクラウド上のアーキテクチャであれば、ポチポチでいいから全体構成を作る
- つまらないアプリでいいので、数時間で作れるものを用意し、各リソースと会話させる
- その上でエラーを起こしてどこに何が出てくるのかを確かめる
- 一部のリソースを消して、あるいは権限を削除して、挙動を確かめる

果たしてこれは簡単に作れるだろうか。
できるのであれば問題ない。そのまま**プロトタイピング**をすればよい。

これ自体に時間がかかりそうなときにプレトタイピングの出番だ。
超ズームインして振る舞いに着目しよう。

仮説：正しいアーキテクチャを**模したロールプレイを行うこと**で、少なくともやりたいことの95%を、登場人物が実演できる

<img src="https://1.bp.blogspot.com/-7eWl_4TVJhc/Viio6UNpGzI/AAAAAAAAzrY/df6-9eIuHKk/s800/engeki.png" height="500">

やり方としてはこんな方法があるだろう。

- 各リソース役の人物を用意する（エンジニア）
- そのエンジニアは与えられたリソースについて理解する（２時間、公式ドキュメントを読み込む等）。その際に重要な視点を例示する
  + そのリソースが何を知り得るか
  + そのリソースが何を操作しうるか
  + 操作に必要な権限はなにか
  + 誰と会話が可能か
- 自身がクライアントとなり実行したいことを指示する
  + DNSに問い合わせる
  + F/E役に情報を尋ねる
  + F/E役は該当するBFF役にデータを依頼する
  + BFF役は必要なドメインサービスに問い合わせる
  + ....
- 最終的に想定した結果は得られたであろうか

形を作ること自体に少し時間がかかってしまいそうだが、プレトタイピング（振る舞いをテストする）という意味では、一つの手段としていかがだろう。
構想するアーキテクチャのプロトタイプを実際に作るために１ヶ月かけるよりも、数日でプレトタイプして問題点を洗い出すほうが議論が活発になるだろう。

そしてなにより、ドメイン境界を試すには、ロールプレイのほうが柔軟で問題を見つけやすい。
知り得ない情報へアクセスしていないか、足りていないドメインはないか、誤った境界のためにコミュニケーションコストが高くないかなど、簡単に試せて簡単に問題点を修正できるだろう[^role_play]。

[^role_play]: ここでは例としてロールプレイとしたが、ロールプレイである必然性はない。ホワイトボードを使ってシミュレートするのが一般的だろう。ただ、複数の頭で実際に動きながらやってみた場合には、さらなる問題点が見えてくることも多いはずだ。

また、副作用として各エンジニアの理解度を向上することにも役立つと考えている[^pretend]。
たまにはこのような余興でチームの交流を図ってみてはいかがだろうか。

[^pretend]: ちなみに筆者は以前、新人研修の中でオブジェクト指向を教えるためにロールプレイを用いていた。参加者をチームに分け、小粒な処理を各自にメインスレッド・クラス・インスタンスなどに扮してもらい、必要な命令・データを一部の人物のみ知りうる状態にするのだ。これにより、オブジェクト指向の動きを理解し、そしてメリットを体感してもらったのである。結果は好評であった。

## プログラムを検証する

さて、プログラムの検証といえばTDD（あるいはBDD）である。
プレトタイピングなどと言わず、TDD、BDDを日常的に行ってさえいればこの考え方はしっくり来るだろう。

### 振る舞いを定義する

なぜその振る舞いを行うべきか、それによって得られる結果は何かを考えて、振る舞いを考えていることだろう。

```rb
Rspec.describe :Greeting do
  subject { Greeting.now }
  it { is_expected.to "Good morning!" }
end
```

そしてレッドになって小さな失敗を経験してから、`Greeting.now`を実装する事により、期待するものが正しく動くことを確認できる。

### 振る舞いをごまかす(pretend)

<img src="https://3.bp.blogspot.com/-CucKHjx9D-4/W8hD6Ap_kWI/AAAAAAABPgs/1Q_f4yz41WkFUHyZyygYbkrqMs7hzpKsQCLcBGAs/s800/monomane_geinin.png" height="300">

では、時間によって返ってくるものが違う場合どうしているか。

```rb
class Greeting
  def self.now
    case Time.now.hour
    when 6..12
      "Good morning"
    when 13..15
      "Hello"
    else
      "Hi"
    end
  end
end
```

```rb
Rspec.describe :Greeting do
  subject { Greeting.now }

  context "when morning" do
    class Time
      def self.now
        Time.new(2019, 12, 2, 10, 0)
      end
    end

    it { is_expected.to "Good morning!" }
  end
end
```

とでもしようか。
ご存知のように、いくらRubyがオープンクラスとはいえ、これはだめなテスト方法だ。
何らかのメソッドをオーバーライドしてテストするのは影響範囲が大きくなりすぎ、テストの有効性を保てない。

そこで現れるのがテストダブルである。
プレトタイピングでいえば、超ズームインしてpretendする方法を考えることと同義だ。

```rb
Rspec.describe :Greeting do
  subject { Greeting.now }

  context "when morning" do
    before do
      allow(Time).to receive(:now).and_return(Time.new(2019,12,2,10,0))
    end

    it { is_expected.to "Good morning!" }
  end
end
```

テストダブルが振る舞いのごまかし方に相当している。

ここではビルトインの`Time`クラスだったが、テストダブルの説明でよくあるAPI呼び出しなどでは、その強力さを発揮するだろう。
なにせ、通信経路の確保、API側の実装、API側の準備を必要とせず、振る舞いに対してのテストが可能なのだ。

### なんと我々はすでにプレトタイピングを知っていた！

# まとめ

- プレトタイピングは様々な場面で役に立つ。
- エンジニアだからこそ、**作らずに評価すること**を大事にしよう
- すでにTDDでもその思想は馴染んでいるはず
- [NO FLOP!](https://www.amazon.co.jp/google%C3%97%E3%82%B9%E3%82%BF%E3%83%B3%E3%83%95%E3%82%A9%E3%83%BC%E3%83%89-NO-FLOP-%E5%A4%B1%E6%95%97%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84%E4%BA%BA%E3%81%AE%E5%A4%B1%E6%95%97%E3%81%97%E3%81%AA%E3%81%84%E6%8A%80%E8%A1%93-%E3%82%A2%E3%83%AB%E3%83%99%E3%83%AB%E3%83%88%E3%83%BB%E3%82%B5%E3%83%B4%E3%82%A9%E3%82%A4%E3%82%A2/dp/4763137492) は超オススメだから読もう！

# 失敗を糧に挑戦を続ける私たちのチームで働きませんか？

失敗を許容し挑戦を奨励する文化の中で、正しく失敗してより良い未来を私達と作りましょう！
チームの中で最も協調性のない人物が小さな失敗と心理的安全性を大事にしているので、失敗を恐れる必要はありません！

![alt](https://brides.a-tm.co.jp/wp-content/uploads/2019/11/ATEAM_BRIDES.jpg)
[エイチーム](https://www.a-tm.co.jp/)は、インターネットを使った多様な事業を展開する**名古屋の総合IT企業**です。
そのグループ会社である**株式会社エイチームブライズ**では、一緒に働く仲間を募集しています！

- [ハナユメ サイト開発グループ](https://jobs.qiita.com/employers/brides-a-tm/development_teams/138)
- [HIMARI開発チーム](https://jobs.qiita.com/employers/brides-a-tm/development_teams/147)
- [技術開発部](https://jobs.qiita.com/employers/brides-a-tm/development_teams/148)

上記求人をご覧いただき、少しでも興味を持っていただけた方は、まずは**チャットでざっくばらんに話**をしましょう。
技術的な話だけでなく、私たちが大切にしていることや、お任せしたいお仕事についてなどを詳しくお伝えいたします！

[Qiita Jobs](https://jobs.qiita.com/)よりメッセージお待ちしております！

# 脚注