フレームワーク・プログラミング言語の技術選定
こんにちは
私は昔、プログラミング言語さえできれば自由自在にすぐ便利なWebアプリケーションが作れると思っていましたが、そうでもないようですね。
現代は研究者同士が情報をやり取りしていたWeb初期とは大きく異なり、多くの人が利用するインフラとしてWebが育ってきました。
パフォーマンスやセキュリティなど多様な面で高まり続けるお客様のニーズに対し、自分でログインやセッション管理にDB接続やリクエストの処理を実装するのはとても大変です。しかもがんばったところで技術的に他者との差別化に繋がるかは別問題ですし、環境変化に対する更新・保守は引き続き大変なものです。
そこで、現在はフレームワークを用いてWebアプリケーションを作成するのが一般的です。
(SIerさんと話していると独自フレームワークにこだわるお客様とか多いらしいですが。。あと個人的に仕組みが気になるタイプなので独自に作っていくことは趣味として大好きです)
今回は新サービスの技術選定にあたり、SpringフレームワークからPlayフレームワークへの変更を検討した際に考えたことを紹介します。
Java + Springフレームワークという選択
現在、Javaを用いたSpring Frameworkを基本的に用いて開発を行っています。
Java
オブジェクト指向プログラミングで、かつ静的型付のコンパイル言語です。JVMという仮想マシンを持ち、ServletやJSPなどWebプログラミングで豊富なAPIや開発環境が蓄積されています。結果として、多くの人が関わる大規模開発を柔軟かつスピード要求を満たすように設計し、堅牢性を持たせながら開発する際に効果を発揮します。
Spring Framework
DIが便利で、かつ豊富なプロジェクトから柔軟性のある設計ができるところが魅力です。結果として、ブラックボックスの少ない開発(ただしアノテーションを除く)、デザインパターンやドメイン駆動開発、マイクロサービスに準拠した疎結合でスケーラブルな大規模開発に効果を発揮します。
Java + Springフレームワークという選択の課題
現在でもこの選択は効果的であると思いますが、一方で現場からは課題も出てきました。
Java
型推論がないこと。NullPointExceptionに悩まされ、null checkが必要となること。複雑な処理を実装していこうとするとnestが深くなったり、メソッドあたりの行数が長くなってしまいがちです。また、シングルトンや副作用のあるメソッドの管理が属人的知識に依存してしまい、他のエンジニアが理解しづらくなってしまいました。
言語としての限界というより管理の問題も多くありますが、管理せずとも保守しやすく安定性のあるコードを書けるような仕組みが欲しいところです。
Spring Framework
pomによる管理や設定の解読に手間がかかります。また、アノテーションによりRESTful APIを設計しても、実際にコードを書いた人以外からはどのようなAPI設計であるか理解するのに時間がかかっていました。
Scala+Playフレームワークという選択
Scala+Playフレームワークは「Java + Springフレームワークという選択の課題」にとても良い解決策を提供してくれます。
Scala
静的型付でありながら、型推論があります。Option型が用意されており、null checkをコンパイル時にできます。また、関数型言語を活かしたコーディングで、複雑な処理もワンライナーで書いていくことが可能です。オブジェクトでのシングルトン管理や、関数型言語による副作用のないメソッドにより、あちらこちらのメソッドを見なくても一覧性のあるコードを書けます。
Play Framework
Railsライクな開発が可能です。具体的には、設定より規約(Convention over Configuration(COC))により、コーディング規約に則ればpomのような設定が不要です。また、routesを軸にしたcontrollerを実装することで、コードを書いた人以外でも簡単に理解できるRESTful API設計を実現できます。
Scala+Playフレームワークという選択の課題
一方、導入にあたっては課題もあります。
Scala
Scalaという関数型言語の学習コストがかかります。プログラミング言語は基本がわかれば、言語ごとにその基本の書き方の違いを学べば、ある程度他の言語も分かるようになります。しかし、関数型言語はCやJava, Ruby等とは基本が異なるので、その基本から学ぶことに学習コストがあります。
Play Framework
これまで作成したSpring frameworkのプロジェクトとの互換性の問題があります。具体的には、比較的マイクロサービスっぽく疎結合で作ってきたので、別プロジェクトとして作成することは問題ないが、packageのインポートができるか懸念です。また、
Springと比較してスケーラブルな設計をしていくことが難しいです。加えて、Playの学習コストがあります。なお、完全に枯れておらずバージョンごとに大幅な変更があることも懸念です。
Scala+Playフレームワークという選択の課題に対する対処
Scala
エンジニアで『Scala関数型デザイン&プログラミング』(通称fpinscala)を用い、言語設計に詳しい方をゲストに呼んで、月次Scala勉強会の開催をしています。併わせて、『Scalaスケーラブルプログラミング第2版』を用いてScalaの勉強をしています。
また、ScalaはJava風の書き方(varを用いる)も可能ですので、あまり学習に比して費用対効果が高くないと判断した箇所はベターJavaとして書くことも可能です。
Play Frameworkフレームワーク
これまで作成したSpring frameworkのプロジェクトはインポートできることを確認しました。Springと比較してスケーラブルな設計をしていくことが難しい点は、これまでの基盤はSpringのままで、新しいサービス開発に利用していく方針で考えています。また、Playの学習については、『Play Framework 2徹底入門 JavaではじめるアジャイルWeb開発』を用いて勉強しています。ただ、Springと比較して(COCやRoutesの部分をブラックボックスと割り切ってしまえば)学習コストは格段に低いと感じています。
まとめ
以上を踏まえて、現在Java+Springフレームワークの遺産を活かしつつも、Scala+Playフレームワークでハイパフォーマンス・安定的な高速開発を新規サービスでできないか検討しています。
次回は、これらの比較が実際にコードで書くとどう違うのか、特にControllerの部分で差が出てくるので説明したいと思います。またScalaも知れば知るほど好きになる言語ですので、紹介していければと思います。