fromscratchで技術選定のときに気をつけていること

こんにちは。フロムスクラッチCTOの井戸端です。一気に寒くなってきて、本格的に"冬！！"って感じですね。
私は北国出身なので、寒くなってくると故郷を思い出して懐かしくなります。

b→dashの開発を始めて約3年、これまで多くの技術を取り入れて開発してきました。(ここでいう**技術**とは、ハードウェア、ミドルウェア、プログラミング言語からクラウドサービスまで、開発に用いる要素全てのことを含んでいます。)
私自身は、特に特定の技術にこだわりの強い人間ではなく、何かを実現するために適しているのであれば使ってしまおうというスタンスなので、基本的に新しい技術を取り入れることに対しては積極派です。

しかし何度か失敗したなと思うこともあり、それらの経験も踏まえて最近では、積極的に取り入れるというスタンスは変わらないものの、採用を決める際に以前よりも多くのことを考慮して、最終的な判断を下すようにしています。

ということで、今回はfromscratchで新しい技術要素を採用する際に、気をつけている観点をご紹介したいと思います。

# 技術選定の観点
技術選定を行う場合、候補の技術そのものに対して評価しつつ、技術以外のことも等しく考慮することが大事になってきます。ある技術が使えそうだから、新しいから、流行っているから等の理由で安易に選択してしまうと、後で大きな痛い目を見ることになります。

## 技術そのものに対する観点
まず何より、採用しようとしている技術そのものに対して、使えるかどうか見極める必要があります。
私は特に以下の観点についてバランスよく判断するように心がけています。

- **課題適合性**：実現したい機能、性能が実現できるか。
- **経済性**：コストが許容範囲内に収まるか。
- **安定性**：適度に枯れているか。バージョンアップの際に後方互換性があるか。
- **将来性**：他に多くの人が採用しているか。定期的にメンテナンスされているか。
- **代替可能性**：いざという時に、他の技術に置き換え可能か。
- **運用保守性**：サポート体制があるか。サポートを活用できるか。

もっとも読めなくて、且つ重要になってくるのが**将来性**です。こればかりは確実にこうと言うのが難しく、ある種エンジニアとしての経験を元に、潮流を読むセンスが必要なところだと思います。目安としては、特に2年後に使われているかどうか考えながら判断するようにしています。何故2年なのかというと、明確な理由があるわけではありませんが、ある技術、サービスが生まれて廃れていくサイクルがおおよそ2~3年くらいの感覚があるからです。
特に近年は、フロントエンドの技術は変遷が激しいので、迂闊に新しいものに手を出さないように心がけています。

あと地味ですがサポートは重要です。特にfromscratchが開発しているb→dashは、BtoBの企業様向けのサービスであるため、運用中にトラブルがあった場合に、責任を持って対応してくれるところがあるかどうかは、サービスとしての信頼性に大きく寄与してくるところです。OSSも多く利用していますが、最悪自分たちで何とかなるものを採用するか、ブラックボックスとして利用するものは、極力サポートがあるかどうかはチェックするようにしています。

## 技術以外の観点
ある技術が適切かどうかは、その技術単体で決まるものではなく、サービス、組織、エンジニアの視点で、全体的に判断することが大事になってきます。

- **適用先サービスの視点**
    - サービス/システムの規模、寿命に適しているか
    - 想定以上にサービスを拡大していくことになるか
- **組織の視点**
    - 現時点で使える人がいるか
    - 今後育成をしていくか
    - 組織の技術ポートフォリオに沿っているか
    - 採用に効果的か
- **エンジニアの視点**
    - エンジニアのモチベーションにプラスであるか
    - 習得までにどのくらいの期間が必要か

特に組織的な視点で「現在どのくらい使える人がいるのか」「今後どのくらい力を入れて育成していくのかどうか(≒育成する余裕があるかどうか)」「他の技術領域を含めて、組織の目指す技術ポートフォリオに沿っているか」などを考えることは、その技術そのものが優れているかどうか以上に重要になってきます。
ある技術を採用するというのは、経営的な見方をすればある種投資をしていることと同義です。目の前の状況だけでなく、今後の開発組織をどう作って行くのかも含めて、採用すべき技術やその時期について判断することが必要だと思います。

# fromscratchでの技術採用の過去事例
いくつかfromscratchで過去新しい技術を採用したときのことを幾つか紹介したいと思います。

## Python
b→dashでデータ処理のワークフロー制御を行うために、Airflowを使おうとしたことがありました。担当のエンジニアからAirflowを使ってデータ処理もPythonで実装したという相談を受け、私自身以前から調べていてどこかで使ってみたいと思っていたところもあり採用を決めました。

ただ結果的にはうまく行きませんでした。
何故かというと、組織としてPythonを扱う余力がなかったというのが根本的な理由です。

実装を進めるうちに、Pythonという言語で日本語を扱うやり方がまだこなれておらず、都度こまごましたことを意識して実装する必要があることが判明しました。それらの意識すべきことというのは、泥臭い文字列処理を実装したことがある人ならあるあるな部分も多いのですが、そうでないエンジニアにとっては、いちいち気をつけなければならないことが多く、実装に非常に時間がかかるともに、潜在的なバグが潰しきれずリスクも孕んでいると感じました。

また、リファレンスも英語が多く、英語の文献を読み解けない人には更にハードルが高い状態だったため、それもまた実装を遅らせ、品質を上げきれない一因となっていました。

最終的に、そもそもAirflow、Pythonを採用する必要性はなく、他の箇所でもPythonをヘビーに使う予定もその時点ではなかったため、組織として時間をかけて使えるようにする投資対効果が薄いと判断し、全てJavaで作り変えるという決断をしました。

最初の時点で、組織的な視点で考えていれば、余分な工数をかけずに済んだなと、今となっては反省しています。
(※ただ、それが適していなかったということがナレッジとして得られたということは財産だと思っています)

## C言語とGo言語
b→dashのメール配信のある処理で、性能を考慮した言語で実装したいという相談を受けました。
b→dashはアプリケーションの多くをrubyで実装していますが、データ処理部などはJavaで実装している箇所も多いので、最初Javaという選択肢もありましたが、対象の処理がメモリが致命的になる処理で、Javaを採用した場合のメモリ管理が逆に面倒だという話から、Java以外で何かないかという話になりました。

最終的に、C言語で実装するか、Go言語を使ってみたいという話になり、Go言語を採用することに決めました。

決定をした要因としては、エンジニアのモチベーションや採用に優位そうだからという理由で採用を決めました。
まず組織として現在CもGoも使っておらず、且つ世の中のエンジニアでfromscratchがアプローチするようなエンジニアは使える人数もそう変わらないだろうなと思いました。そうなったときに、社内のエンジニアとしてはGo言語の方がモチベーション高く取り組むことができるということと、今後の流れを見るにGoはより使われていくだろうということを考え、Go言語を採用することに決めました。

まだなんとも言い切れないところはありますが、開発に関しては全く問題なく進んでおり、エンジニアのモチベーションとしてもプラスになっているので、よかったのではないかと思っています。

# 最後に
長々と書いてしまいましたが、技術選定は会社の技術の方向性を決める重要な判断であり、経営的な視点から総合的に検討を行い最終的な判断を下すべきものだと考えています。今でも悩むことは多いですが、都度そのときの状況から判断していきたいと思います。