ボクココ

サービス開発を成功させるまでの歩み

プログラマのための SQL を読んで

ども、@kimihom です。

今回は以下の本をざっと読んだので感想を書く。760ページにもなる超大型本だ。

プログラマのためのSQL 第4版

プログラマのためのSQL 第4版

SQL でここまでできる

私は普段、Web アプリケーションのコードを書くエンジニアなのでデータベースの知識はそこまで深くない。よりデータベースの知識を深めようということで本書を手に取った。

本書の前半部分は SQL の一般的な教養的な感じで学ぶことができた。いきなりトランザクションの話が出てきたときはマジかよって思ったけど、そのあとは SQL の各句の詳細な解説などもあった。

一番ここで感じたのは、「NULL の扱いの難しさ」だったように思う。NULL は SQL の中で本当に特異的な存在で、実際にクエリを書くときも注意しないと意図しない結果を生むことにもなりかねない。本書でにおける NULL を扱うことで意図しない結果を生んでしまう SQL の例がたくさんあったので、やはりテーブル作る時に NOT NULL にして初期値をセットするのは大事だなと改めて感じた次第である。 例え NULL を許容するカラムがあったとしても、COALESCENULLIF などを使って丁寧なクエリを書くことを意識したい。普段 Rails を使っていると ActiveRecord で隠蔽されちゃうけども、何か困った時にはちゃんと自前でしっかりとした SQL を組み立てられるようにならないといけない。

本書の後半部分では SQL を駆使したテクニック的な側面が強かった。SQL も1つの立派なプログラミング言語であるので、複雑な問題を SQL “だけで” 解くことができたりする。当然それはそれで SQL を極めるって意味では本書の意図に適っており、学ぶことはあった。しかし、実際にそれを解くってなるとやはり私は Ruby や JavaScript などのプログラミング言語で解きたいなと思う。

グラフや木構造を SQL で扱う話もあった。当然、SQL はそのような設計で作られてはいないので、トリッキーな構造でテーブルとして管理する必要がある。でも実際 SQL でこういうデータ構造を扱うことってどのくらいあるのかと疑問に思った。最近では Neo4j などのグラフ志向データベースなどが出てきているので、適材適所なんじゃないかなと思った。そういう意味では後半はちょっと流し読み程度で読み終えた。

とは言いつつ、"SQL" は今後も廃れることのない技術の基礎として残り続けるだろう。新しい技術が出てきても SQL ベースになっていることが多く、UNIX などの OS の基礎といった同等のレベルで必要な知識だ。そういう意味で改めて一気に本書を読みきったことは、今後の Web アプリケーション構築の糧となるだろう。

集約機能の拡充

最近の SQL の潮流(?)的なものとして集約を SQL で活用できるような流れを感じる。BigQuery とかも SQL で大規模データにアクセスする感じだ。私たちが普段書いている Web アプリケーションのコードと違って、集約の SQL は複雑なクエリを書けるようになる必要がある。本書を読みたいと思った動機もそこにあった。

ただ本書は “SQL のすべて"ってことなので集約に関しての記述もその中の一部としての解説だったし、PostgreSQL に特化したって話でもないので実際に集約のみを重点的に学ぶとなると他の本の方がいいかもしれないと思った。私は以下の本をプログラマのための SQL を読む前に読んだのだけど、学ぶことが多くて良かった。大抵の Web エンジニアであれば本書を読むだけで十分な気もする。

SQL実践入門──高速でわかりやすいクエリの書き方 (WEB+DB PRESS plus)

SQL実践入門──高速でわかりやすいクエリの書き方 (WEB+DB PRESS plus)

また、集計の本格的な実例として以下の本も参考になった。特に PostgreSQL などの DB に最適化された内容で実践に即した内容なのですぐに使える知識として有意義だった。

ビッグデータ分析・活用のためのSQLレシピ

ビッグデータ分析・活用のためのSQLレシピ

私が直近で学んだデータベースに関してはそんなところだ。

終わりに

最近はブログ更新のアウトプットよりもこうしたインプットを重点的にやってきた。エンジニアは表面的なところ(プログラミングやフレームワークなど) を抑えたら次は裏の部分(OS, データベース, プログラミング言語そのもの) といった部分に興味というか、自分にとって必要だと感じるようになるのだろう。今回はその一環として “SQL” をテーマに深く学んできた。

次に作りたいものの大枠が見えてきたし、今回得た知識を活用して、またプログラミングをどんどんやっていきたい。

Rails コントローラ内の define_method 活用例

ども、@kimihom です。

今日はちょっとした Rails の小ネタ。Ruby にはご存知の通りメタプログラミングというトリッキーな開発方法があって、これが良いだ悪いだの議論が絶えないわけだけども、ちょっとしたことで便利に使える時がある。

今回紹介する define_method は、コードでメソッドを定義できる手法だ。以下のような感じで class 内でメソッド定義できる。

class MyClass

  define_method(:say_hello) do
    puts "hello world."
  end

end

MyClass.new.say_hello #=> hello world.

さてこの define_method だけど、 Rails でもそれなりに便利に使える時があるので活用例をご紹介する。

同じ(似た)実行内容のメソッドを一括定義

例えば Rails でランディングページを作っていた場合、大抵は View の表示だけ変わる、至ってシンプルなコントローラができるはずだ。しかし、その中で例えば “og:title などのメタタグなどは layout 内の @og-title をセットしないといけないので、コントローラ内でそれを定義したい” といったことが出てきたとしよう。今回の記事ではこういうニーズが出てきたっていうことにしておいてほしい。

そん時に define_method を使うとこんな感じでかける。

class LandingPagesController < ApplicationController

  [:welcome, :feature, :terms, :privacy].each do |m|
    define_method(m) do
      @og_title = t("landing.#{m}.og_title")
      # ...
    end
  end

end

このサンプルでの"before_action" に書けばよくね?のツッコミはナシでお願いしたい。 わお、これで View に @og_title を渡すことができた!しかもバッチリとアクション別の文言に変えることができている。

このくらいシンプルな共通処理だったら同じようなメソッド定義がつらつらと書かれているよりも、スッキリして見やすくなるかと思う。こんな感じでちょっとした手間を省く上でも、define_method をチョロっと活用してみることからお薦めしたい。

メタプログラミングを学ぶ

Ruby のメタプログラミングといえば、以下の本が有名だ。当然、私も本書を読んで Ruby の魔力に惹かれたものである。

メタプログラミングRuby 第2版

メタプログラミングRuby 第2版

この本を読んだ途端、きっとmethod_missing などの Ruby の魔力を使いたくなるだろう。「オレ、Ruby 使いこなしてるぜ」感が出てくるからだ。しかし、一旦落ち着いてほしい。メタプログラミングを乱用すると、メソッド定義がどうなっているのか、誰も理解することのできない状態 を生みかねない。

Ruby にはインスタンスメソッド一覧を表示してくれる methods という大変便利なメソッドが用意されている。メタプログラミングを乱用すると、methods などの出力にそれらが出てこなくなり、後でどうやって使えば良いのか、そもそもそのメソッドは存在するのかを確認することが困難になる。

なので、メタプログラミングの乱用は自分の趣味の範囲で実験で使ってみて、実際のプロダクションのコードでもちょっとだけ入れてみる程度から始めてみよう。いきなり Rails の Model でメタプログラミングを多用すると確実に痛い目を見ることになる。ここまで言い切れるのはなぜかというと、実際の経験者がここにいるからである。

終わりに

今回は Ruby のメタプログラミングの最初のとっかかりだけ紹介した。

「大いなる力には大いなる責任が伴う」とはよく言ったもので、メタプログラミングを活用すれば一部のコード量が劇的に下げられたり、今まで実現不可能だったほどの柔軟性のあるコードを実現できる。メタプログラミングのトレードオフを理解した上で、確実安全なプログラムを書いていこう。

そしたら、一段階上の Ruby プログラマになることができよう。

Elasticsearch と Rails のデータ同期方法

ども、@kimihom です。

f:id:cevid_cpp:20170905190744p:plain

全文検索の仕組みとして Elasticsearch を使ってサービスを運用している。Elasticsearch と Rails を使っている上で考慮しなきゃいけないデータ同期の方法について、それぞれのメリット/デメリットを紹介した上で最終的な提案まで記す。

本記事は Elasticsearch-Rails を利用した場合となるので、基本的な使用方法などはリンク先を参照いただければ幸いだ。

GitHub - elastic/elasticsearch-rails: Elasticsearch integrations for ActiveModel/Record and Ruby on Rails

では ActiveRecord と Elasticsearch でのデータ同期方法についていくつかご紹介しよう。

方法1. ActiveRecordコールバックによる同期

まず一番簡単な elasticsearch-model を使った ActiveRecord コールバックの方法だ。これは、ActiveRecord オブジェクトで 作成/更新/削除 されたタイミングで Elasticsearch のデータもそれぞれ更新する方法である。

class Article < ActiveRecord::Base
  include Elasticsearch::Model

  after_commit on: [:create] do
    __elasticsearch__.index_document
  end

  after_commit on: [:update] do
    __elasticsearch__.update_document
  end

  after_commit on: [:destroy] do
    __elasticsearch__.delete_document
  end
end

ほとんど 登録/更新処理のないサービスの場合だったら、この方法で十分だろう。まずは ActiveRecord コールバックで問題ないか試しにやってみるといいと思う。

この方法のデメリットは2つある。1つは ActiveRecord オブジェクトの作成/更新のたびに Elasticsearch との接続が走ってしまって1つ1つのリクエストが重くなる点だ。当然 Rails サーバー側と Elasticsearch のサーバーは分けることになると思うので、その間のネットワーク接続で処理を待たされることになる。 2つめは ActiveRecord 限定で使っていかないといけない点だ。例えば裏側で PostgreSQL を使っていて、生の SQL でレコードをアップデートしても Elasticsearch 側に反映させることができない。あくまで #update#create などの ActiveRecord のメソッドを呼ばない限り Elasticsearch に登録されない。これは運用時に結構ネックになることがあるので気をつけたいところだ。

方法2. バッチ処理で一括取り込みを行う

もう一つの方法は elasticsearch-rails を使って一括取り込みを行う方法だ。

これであれば、前者のパフォーマンス問題と、生SQL で同期できない問題を解決できる。具体的には、以下の rake タスクを定期的に実行するような形となる。

bundle exec rake environment elasticsearch:import:all

これは、include Elasticsearch::Model が読み込まれた ActiveRecord モデルを一括で読み込み、その全データを Elasticsearch に投入することを意味する。全データなので、これが1万件くらいあると、当然無駄に時間がかかってしまう。 そして時間がかかるということで 1時間に1回の実行にしてしまうと、その間に登録されたデータは検索対象に入らなくなってしまう。この問題をなんとか解決したいところだ。

方法3. コールバックと バッチ処理の混合技

最終的なオススメは、上記2つを混合させる方法である。方法2で紹介した rake タスクは、対象の scope を指定することが可能だ。

bundle exec rake environment elasticsearch:import:all SCOPE='recent'

ActiveRecord 側で今回適当に用意した recent スコープを定義してあげる。

class Article < ActiveRecord::Base
  include Elasticsearch::Model

  scope :recent, -> {where("updated_at > ?", 1.hour.ago}

end

これで更新日時が 1時間以内のデータを一括で取ってきて、それだけを Elasticsearch に登録することが可能だ。しかし、この方法をしてしまうと、データ削除に対応できない という新たな問題が発生する。方法2の一括読み込みの方法では削除されてもデータ同期ができたが、今回は差分だけなので削除したレコードを取ってこれないのである。

てことで、削除の時だけ 方法1のコールバックを活用しよう。今回の結論としては以下のような形となる。

class Article < ActiveRecord::Base
  include Elasticsearch::Model

  scope :recent, -> {where("updated_at > ?", 1.hour.ago}

  after_commit on: [:destroy] do
    __elasticsearch__.delete_document
  end
end

そして以下のコマンドを10分に1回などの Cron で回すようにしよう。

bundle exec rake environment elasticsearch:import:all SCOPE='recent'

1時間前の更新日時にしたのは、その間で Elasticsearch の同期に失敗しても、10分に1回なら6回のチャンスを与えるためにそうした。 import 自体は重複しても上書きするだけなので、確実にデータ同期する上でもこの方法で良いと思う。そしてこの方法なら、PostgreSQL の生 SQL でレコードをアップデートしたとしても、updated_at を正しく更新さえずれば Elasticsearch のデータ同期対象となる点も魅力的だ。 ※外部SQLでの削除 or ActiveRecord#delete(_all) 等は同期無理なのでやらないでね。

終わりに

今回は Elasticsearch Rails を使った活用方法をご案内した。

最終的には方法3をオススメしたけども、これはデータがリアルタイムに反映されるってわけでもないので、これでも完璧とは言えないとは思う。リアルタイムが求められるサービスなら、方法1 の同期処理を ActiveJob でバックグラウンド実行すること(方法4)を検討する価値もあるだろう。

本記事が Elasticsearch と Rails を使っている方に参考になれば幸いだ。

モチベーションを保ち続ける

ども、@kimihom です。

f:id:cevid_cpp:20170902185410p:plain

今回は以下の本を読んだので感想とやっていきたいことみたいなのを書いてみる。かなりいい本だったので、モチベーションに関して興味ある方はぜひ読んでみることをオススメする。

モチベーション3.0 持続する「やる気!」をいかに引き出すか (講談社+α文庫)

モチベーション3.0 持続する「やる気!」をいかに引き出すか (講談社+α文庫)

労働に対する考え方の変化

モチベーション 3.0 とあるからには、1.0, 2.0 があるわけだ。ざっくり言うと、生きるために働いてきた1.0 と大量生産のためのマニュアル化/機械化を推し進めてきたのが2.0だ。

3.0 はどんな時代背景があるのか。それは単純作業だけでまかり通っていた 2.0 から、より創造的な仕事が求められてきていることが背景にある。私たちの人間の仕事はより高度になり、より柔軟な発想が必要な仕事がこれからもどんどんと増えていく。そんな中、今の日本の企業は 2.0 的な考え方の企業が多すぎるように思う。

3.0 の特徴は、個人の意志を大切にする企業文化だ。自由な出勤時間、何でも自由に開発できる時間を設ける、一人一人の所属意識でなくオーナーシップ、上司は部下を管理しない。ここで面白い実験内容があったので本記事でも概要だけ紹介したい。

とある学生の集団を AとBに分けた。Aはその作業をすると報酬が与えられると事前に約束され、Bは特に何もアナウンスをしないで作業をしてもらった。誰でもできる頭を使わない単純作業を A, B それぞれにやらせたところ、Aははりきってその仕事をすぐに終わらせた。今度は頭を使う創造的な課題をやらせたところ、今度はBの方がAよりも早く課題をクリアすることができた。

これは、まさに人参の目の前にぶら下げた馬のような表現だ。目の前に人参しか見えない馬は、その人参のためだけに走って正しい道を選ぶことができないのである。そして人間でもこの目の前に人参がぶら下がっているのを追い続ける人たちが後を絶たない。

モチベーション3.0 はその先を見なければならない。今目の前にある利益ではなく、今努力した結果生まれる利益だ。それが続く限り、人はどんどん大きく成長し、今まで辿り着けなかった利益を得ることができるのである。

良い目標と悪い目標

目標に向かって努力するモチベーションは当然大事だ。しかし、良い目標と悪い目標があって、いとも簡単に誤解するので注意したいところである。さて、皆さんがお持ちの目標は、以下のどちらだろうか。

  1. フランス語の授業でAをとる
  2. フランス語を話せるようになる

一見、具体的で到達可能な目標だとして 1 を選びがちだ。それはそれで良いとされることもある。確かに、1 でも Aを取るという目標のためにテスト期間に頑張ってフランス語を勉強することはできる。しかし問題はそこからだ。 1 の場合、Aを取った途端に露頭に迷うことになる。もはや次の目標が見つけられないため、次のテストまではフランス語とは一切関わらないことだろう。しかし、2はあくまでテストは通過点に過ぎないので、テストが終わってもフランス語の勉強をコツコツと続けていくことだろう。この違いがやがて大きなものとなって、最終的には 2 の目標を選んだ人が成功を掴むのである。

これは企業にも同じことが言えるだろう。営業目標や利益目標などを掲げて目の前の数値だけを追い続ける人がいる。数字にとらわれて、その数字目標を達成するためなら手段を厭わないような、そんなやり方だ。それは結果的に不正を招くことになる。なぜなら数字を達成できないとわかったら、何が何でも達成させようと、"どんな手段を使ってでも" という考えに陥ってしまうからだ。 しかし、理念ベース、つまりフランス語を話せるようになるといった企業目標に向かっていればそんなことは決して起こらない。なぜなら、そのような不正をしてしまっては結局自分に返ってくることを知っているからだ。テストでカンニングしたところで、フランス語は上達しないのは当たり前だろう?フランス語を話せるようになる目標にしているのに、そんな不正をすることに全く意味はないのだ!

達成したら次の数値目標を掲げてブラック企業としてがむしゃらに働く姿勢が日本では評価されている傾向がある。しかし、もうそんな気合い論は時代遅れであることを知るべきではないだろうか。

漸近線を描く目標を考えよう

最終的にどんなに近づいても達成することのできない目標を掲げること。どんなに成長しても、まだまだ自分は成長できると信じ続けること。それが私たちをより高みへ連れていく。

それは、誰かからとやかく言われるようなものではない。自分が心から達成したいという理想の状態を見つけ、それに向けて努力を続けるのである。その努力は自ら沸き起こるモチベーション3.0なので、ずっと続くもので、他の誰よりも良い結果を生むことだろう。

それは地味で辛く険しい道でもある。それを知った上で続けることができれば、尽きることないモチベーションを持ったまま、成長し続けられる仕組みを得ることができる。

終わりに

最近、私がぼんやり考えていたことが、そのまま明文化されていたような本だった。

本当に成功している企業ってのは実はこのような社員のモチベーションを最大限に引き出す仕組みを既に活用していて、人海戦術な古来の方式を取る企業のその先を行っている。

もちろん、モチベーション2.0 のような仕事を続けるのも良いだろうけど、私はモチベーション3.0のような、主体的な行動が推奨されるような、そんな仕事を続けていきたいと思う。だからこそ、自らを磨き続けることの重要性を知り、終わることのない自分の理想に向けて努力を続けていく次第である。

エンジニアの生産性は人数で変わるのかについて

ども、@kimihom です。

“エンジニアの人数とプロダクト開発の生産性は比例しない” とよく言われる。実際私はこれは正しいと思っていて、今まさに1人エンジニアで高い生産性を実現している。本記事では人数とプロダクト開発の関係について自分の考えをまとめてみる。

1人なら開発以外で必要なあらゆることが省略できる

開発と言ってもたくさんの"決めごと"が必要になる。設計やレビューは特にその中で大切なものとして扱われる。人数が多ければ多いほど、設計書を事細かに書くことは重要だ。そして設計書だけでなく、コミュニケーションロスによって設計者が意図したものがそもそも完成しないということも頻繁に発生してしまう。人数が多いと、開発する能力に加え、相手に正しく設計の中身を正しく伝え理解する能力が求められる。

おっと、ここで1人で開発すれば設計能力が不要になるということではない点に注意だ。1人でも正しく設計する能力は当然求められる。しかし、それをドキュメントに事細かに書き起こしたり、合意形成をとったり、ドキュメントを正しく読んで実装するといった作業は不要になる。自分の書いたメモやページを元に構築していけばいいので、そのあとのあーだこーだいう時間を一気に省略して一番大事な「開発」に取り組み始めることができるのだ。このように、開発スタート時点で大きな差が生まれる。

レビューやペアプロなど、1人エンジニアの環境ならそもそも不要だ。経験豊富なエンジニアはどこにどんなコードを書くべきかわかっているし、もし途中で間違えたとしてもすぐに修正していくことで 、そもそも 問題が発生しにくいコードを書くことができる。誰かからとやかく言われるレビューやペアプロと違って、自分が身をもって経験した失敗なので、自分のスキルとしてどんどん蓄積していくことができる。"コードを書くことでプログラミングを学ぶ"のだ。当たり前のことだけど、経験豊富な人がプログラミングをしないようなケースが増えてきているように感じるのであえて書いてみた。

コードを書かないエンジニアはただのエンジニアだ。

例えばプロジェクトの途中で仕様変更があったとしよう。1人で全てを作ってきたエンジニアの場合、システムの全てをコードレベルで把握しているため、どこをどう直すべきかが一瞬で頭の中で組み立てて修正を始めることができる。実際にそのような素早い修正能力は、特に生産性において重要なことだ。人数の多いチームで見たこともないソースがあちこち出てくると、どこをどう直すべきか、開発した1人1人が話し合わないといけないし、その度に今まで蓄積したドキュメントを更新しないといけないし、修正した分をレビューしなければならない。どちらの方が素早く行動できるのか、一目瞭然だろう。

人数の多さでプロダクトの質はどう変わるか

人数の多さは開発効率以外にも影響を受ける場合がある。プロダクトそのものの質だ。

少人数で考えられたプロダクトは、最初に作ろうとした思いやターゲットが明確に浮かび上がっている。そんな思いがなければそもそも作り始めることすらできなかったことだろう。

しかし、人がどんどん増えてくると開発当時の思いを持った人が少なくなってきて、"とりあえず便利そうな機能作る" 程度のプロダクト開発メンバーが揃ってきてしまう。途中から増えてきた社内メンバーであるエンジニアやデザイナー、PM は、サービスに対する思いを実現するよりも目の前の仕事をこなして給料を得るという考えに至る人が出てくる。

てなるとプロダクトは人数に比例してどんどん Fat になっていって、誰のためのサービスだかわからなくなる。たとえ人数が増えて多少開発効率が上がったとしても、プロダクトが改善されていかなければ、その時間とお金は無駄になる。実際そんな無駄に人が多いプロジェクトで失敗することは、何回かプロジェクトをやってきたことのある方なら1度や2度あるはずだ。

それでも大人数で上記課題をクリアできる方法がある。"独裁者レベル" の決定権を持つ人が指揮をしていく方法である。その独裁者の"思い"が完全に詰まったプロダクトでなければ、ゼロからでも作り直させる。従業員はとても辛いことだけど、それくらいの独裁者でなければプロダクトは中途半端に仕上がって、市場に誰も受け入れられない結果を招くことになる。そんな独裁者レベルの人の企業に務めるエンジニアってのは完全に奴隷みたいなもんで、上から言われたことを100%守らないといけないような、そんな辛い仕事が待っている。それは確かにサービスを成功させる上で大事なファクターではあるんだけど、そもそも仕事に辛さが出てしまうようでは何のために働いているのかもわからん状況が生まれてしまう。

だからこそ、少人数で意思決定できるくらいのスモールチームが今後より求められてくると思う。少人数のチームならそんな意思決定を一人ひとりができるし、誰か他人によってそれが折り曲げられたり言いづらかったりすることが発生しない。それでいて自分から作りたい理想のプロダクトを磨き上げることができるので、運営元もユーザーもハッピーになれるプロダクトが生まれる。

そんな訳で、少人数で開発することでプロダクトの成功確率も上がると私は考えている。

終わりに

今回の記事は、私が今まで経験したプロジェクトの中でどのプロジェクトが良くてどのプロジェクトが悪かったのかを振り返って、人数の大小は大きな影響を与えているという思いから書かれたものである。

大人数のプロジェクトしか経験したことない方は、ぜひ少数のチームでやってみてほしい。逆に少数のチームでしかやったことない方は、大人数のプロジェクトを一度でも経験してみるといいと思う。そうすれば今回の記事がどうだったのかを身をもって体験できることだろう。

今回の話は「優秀な」少人数のエンジニアという前置きを置いている通り、優秀でない限り当然開発効率は落ちる。優秀になるためには、とにかくプログラミングをし続けて経験するしかない。だからエンジニアは開発手法に頼ったりしないでプログラミングをするということを意識していってほしいなと思う。

さてプログラミングを、はじめましょう。

オンリーワン企業になるために必要な仮説

ども、@kimihom です。

ナンバーワンにならなくてもいい、もともと特別なオンリーワン。

f:id:cevid_cpp:20170824233211p:plain

ということで、インターネット企業でオンリーワンを目指すにはどんな企業になっていく必要があるのか。下記の項目は私の仮説ではあるけども、理由とともに記して行こうと思う。

オンリーワン企業の魅力

オンリーワン企業はプロダクトを作る側/使う側どちらもハッピーになれる。

企業は使ってくれる特定の顧客のことだけを考えれば良い。自分のサービスを気に入ってくれた人だけに最高のサービスを提供するのだ。そうして企業と顧客の関係はより密接になり、いつまでも通い続ける常連の店や老舗旅館のような関係になっていく。

こうして企業はより一層、特定顧客のために素晴らしいサービスを提供しようと努力できる。新入りお断りくらいなレベルにすることで、特定の顧客はさらに熱狂的な顧客となり、強い信頼関係の中でビジネスを進めて行くことができるだろう。

強い信頼関係こそが、企業が安定して"継続"していくための土台となるだろう。一発当たって大成功イグジットしてゴールみたいな、そんな考え方には決してならない。人生は長い。自分の渾身の力作プロダクトを、顧客に永く使い続けてもらうことが、オンリーワン企業を目指すことの大きな価値なんじゃないだろうか。

ではそんな企業になるために必要なことを仮説として理由と共に挙げていきたい。

マスを取りに行かない

インターネットでビジネスをやっているなら、日本/世界を取りに行かないといけない。そんな固定概念のようなものが決まり切ったものになったのは、きっと大成功した Google などの企業しか普段見る機会がないからだろう。しかし、実際は一部の人だけに熱狂的に愛されているオンリーワンのプロダクトってのも存在する。

オンリーワンのプロダクトは、"特定のターゲット層にのみ熱狂的に支持されるプロダクト"である。特定の人たちがこれ以外考えられないというレベルのプロダクトに磨き上げる。ターゲットを明確に絞ったプロダクトは、その人たちだけが好んで使う機能を実装したり、他の層では必要な機能をあえて入れずに機能を簡素化することができる。一部の人たちだけに「まさにこれが私の求めていたプロダクトです」と言ってくれることがゴールだ。他の人から見れば、ニッチだと思われてあまり参入して来なそうな領域。そうすれば競争が発生することもないし、私たちプロダクト開発者はずっと顧客のことだけを見ればいいことになる。

マスを狙ったサービスでは実現することが不可能な領域である。オンリーワンな考え方は、資金調達をするとほぼ不可能になるだろう。得てして資金調達を受ければイグジットを求められるので、"マス"を取りに行かなければならない。一部の熱狂的なファン"だけ"に愛されるオンリーワンのプロダクトというよりは、特定の業界を独占するナンバーワンになることが求められる。既存の競合を蹴散らして、ユーザーを囲い込んでいかなければならない。そんなピリピリモードでビジネスをして行く必要がある。勝ったものだけが幸せ(?)になれる世界だ。

“オンリーワンかナンバーワンか” は人それぞれの考え方や価値観によって変わるものだから、全員がオンリーワンを目指す必要はないと思う。が、ナンバーワンになることしか知らないような人が多いような気がするので、もうちょっと書いていくとする。

成長よりも顧客の関係を大切にする

現場に1人しかいなくて仕事を分散できない状況にいた時、あなたは以下のどちらの企業を優先的に対応したいと思うだろうか。

  • 見込みありの大手上場企業で、"貴社のサービスに興味があるからぜひ一度弊社に来てくれないか" という提案
  • 既存顧客で、"このサービスのこの部分の使い方がわからないので来て教えてくれないか"という相談

企業の成長を重視しすぎると、既存顧客のことを置き去りにして(当人はそんなことないと言うだろうが)広告を出したり余計な機能開発をしていったりすることが発生する。そうしないと新しい顧客を得ることができないからである。しかしオンリーワン企業はそれよりも今使ってくれている顧客のことをより知ろうと努力し、その顧客のために機能を洗練させていく。

上記の質問はとても大事で、その現場にいる人全員が"既存顧客"を選べるような状況にないとオンリーワンになることは厳しいと思う。なぜなら前者を選ぶってことは、営業や広告に重点を置くって意味であり、先ほどのマスを取りに行こうとする考え方に近いものがあるからである。

改めて記すが、前者を選んでも決して間違いではない。人それぞれビジネスのどこに重きを置くかっていう話の例として捉えていただけたら幸いである。

終わりに

オンリーワン企業になって顧客と厚い信頼関係で結ばれた中でビジネスをする。そのビジネスで影響を与えられる人は少ないかもしれないけど、一部の人が幸せになれるならそれもビジネスとしてれっきとした大成功なんだと私は思う。

誰でもアクセスできるというインターネットの性質上、どうしても日本中、世界中ってことに目が移りがちだ。でもあえてインターネットの世界で老舗旅館を目指すのも面白いんじゃないかという仮説を立てて行動している。そしてその仮説は正かったと証明されつつある。

キミは本当の MVP を作れるか

ども、@kimihom です。

新サービス開発においてよく言われる “MVP (Minimum Viable Product)” ってのがあるけど、これを本当に実践できている人はどのくらいいるのだろうか。

今回はよくある勘違いと私の考える正しい MVP の作り方について記していきたい。

とりあえず最小限の機能を作って出す

MVP は言葉の通り「最小限の機能を持ったプロダクト」だ。とりあえず最小限の機能を作って出すってところまでは特に誰でも問題なくできるだろう。 しかし大事なのはそこからで、もしMVPの検証でターゲットに確実に刺さっているものでないと分かれば、ゼロから作り直すって判断が必要だ。しかし実際は「この機能修正/追加によって対応しよう」レベルの判断になってしまうことが多いのではないだろうか。もはやそれは MVP ではない。そういった安易な判断をしてしまうと、本当に顧客の望むものをいつまで経っても作り上げることはできない。

以下の図は MVP に対する説明としてよく表現されているので引用させていただく。

f:id:cevid_cpp:20170822212845p:plain

4 Reasons Minimum Viable Products Fail

この「ゼロから作り直す」って判断ができないと、最終的に顧客にドンピシャな商品ってのはいつまで経っても作れない。それどころか、機能追加に無駄に時間を使ってしまって誰のためのサービスなんだかわからないものができあがってしまう。

本当の MVP とは「顧客にドンピシャな最小限の機能を見つけ出すプロセス」だ。ちょっとでも最初の MVP で顧客に刺さらないものを作っているというフィードバックを得たなら、本当にゼロからぶち壊して作り直せるか。この判断とスピード感こそがビジネスの成功を左右する。

インフラ構築やデータベース設計に時間をかけすぎてしまってもう後には戻れない?テストコードを丁寧に書いてきたのに?せっかく今まで頑張って作ってきたのにもったいない?そんな判断が続いていくと、確実にこの MVP を作り上げることはできないだろう。

どんどん作ってどんどんぶっ壊して作り直す。そんなことが可能なインフラ構成、技術選定、コード設計を考えられるか。スタートアップの開発で大事なのはそんなスピード感だ。

作ったものを上司に見せて承認を得てもらう必要がある?そんな古臭い体制ではいつまで経っても当たるか当たらないかの宝くじを引いているのを繰り返すだけだ。せっかく時間をかけてプロダクトを作るなら、その1つの製品で確実に顧客の心を捕まえられるようなシステムを作ろう。そのためにも使ってくれる顧客を見ながら上司の承認関係なく現場レベルで判断を下しながら MVP の開発をすべきだ。そんなスピード感がなければ、確実に「もはや後戻りできない」プロダクト開発となってしまってMVPとは程遠い、ダラダラと誰が使うわわからない機能開発という最も意味のない時間を費やすことになるだろう。

スタートアップエンジニアは何を鍛えるべきか

もはや感覚でソースコードを綺麗にできるレベルのエンジニアが最終的には勝つと思う。いちいち設計やソースレビューで時間をかけたりしてたらそれだけで時間がかかってしまう。関係者が5人以上いてもいいけど、全員が話し合わずともある程度の合意形成できる成熟度にないと、わざわざ確認することが多発し、ゼロからぶっ壊して作り直すっていうスピードを実現することができない。その果てに必ず後戻りできないようなシステムを作り上げてしまうことだろう。

そのためにも、ゼロからプロダクトを作った経験がたくさんあるエンジニアこそスタートアップエンジニアに向いていると考えている。どんなゴミプロダクトでも、それを開発すればゼロから作った経験を持つことができる。そこで失敗した設計やコーディング方法などを次のプロダクト開発に生かすことができる。何回もゼロから作った経験によって、次のプロダクトはより早く、変化に強く、美しくプログラミングしていくことができる。1つのプロダクトの開発運用しているだけのエンジニアではいつまでもたどり着けない地点だ。

さらに理想を言えばそのゼロから作ったプロダクトでそれなりにユーザー数を持つ何かがあると良い。ユーザーが増えてきて初めて経験することも数多くあるからである。そのサービスで初めてそれなりの規模のサーバー運営や、パフォーマンスを意識したコーディングなどを実感しながら成長することができるだろう。そうやって一度でもうまくいったプロダクトをゼロから作り上げた経験があると、次のプロダクトはより良いものになって成功を生み出しやすくなる。

企業に勤めながら、ゼロからプロダクトを作る経験をたくさんできるか?それは異動や転職を繰り返さない限り不可能だ。しかし異動や転職を繰り返してしまうといつまで経っても本当の自分のプロダクトにめぐり合うことはできない。てことで、いかに個人の時間を使ってプロダクトをゼロから作る経験を持ち続けられるかが大事になる。

よくある業務時間外で勉強/開発すべきかどうかって話だけど、個人で開発をする訓練をしない限りは、正しい MVP を高速で回すことができず、成功するプロダクトをいつまでも作ることはできないだろう。その上でやる/やらないの判断をそれぞれがすればいいと思う。

終わりに

今回は MVP について割と真剣に考察してエンジニアの鍛えるべき道筋をご紹介した。

最初のアイディアで確実に成功するプロダクトを作るってのは本当に難しく、できたら奇跡レベルだ。そうじゃなくて、ぶち壊しながらも確実に顧客の理想に届くプロダクトに磨いていく、そんな俊敏な開発ができるエンジニアを目指すことで、自分のプロダクトを成功まで導くことができる。

スピード感を持って大胆な決断ができる企業が増えていくと、面白いプロダクトがどんどん出てくると考えている。