アーキテクチャ設計の一部に、プログラミング言語の選択があります。選択に関わるのは仕事では10年振り(うん? ちゃんと数えると13年か・・・)です。3月から下調べを開始して、可能な限り公平に。
もちろん人間の判断なので、主観が大きく関与せざるを得ません。特にプログラミング言語は、パラダイムの選択になるので。
前提の明確化
技術選定にあたっては、前提を明確にしておかないと、果てしない議論に陥ってしまいます。
ここでは、開発対象をエンタープライズ・システムとします。エンタープライズ・システムは、開発期間よりも運用(保守)期間が数倍(たとえば、開発1年に対して運用10年といったことも珍しくない)になります。また、システム化範囲も昔に比べて増えてきており、その分作成されるアプリケーション規模(機能量)も大きくなります。
また、運用(保守)期間では、随時機能の変更・追加が行われる想定とします。
システムは地理的に分散して運用されます(いわゆる本店・支店・工場、等)。
システムは24時間運転されます。
システムはWeb前提ではありません。
比較のポイント
運用期間を通して、技術が安定して存続していることが最大のポイントです。運用期間が長くなれば、ネットワーク機器・計算機・OS・ミドルウェアなどは当初のモデル・バージョンが入手できなくなり、更新を余儀なくされます。また、運用期間中に処理能力向上の必要が生じたときも同様に新しいモデル・バージョンにならざるを得ないこともあります。そのとき、開発したアプリケーションを載せ替えるために支払うコストがどれだけになるかが選定のポイントです。
バイナリ互換>ソース互換>ソース修正
の順になります。
オンライントランザクション、データベース連携、分散システムについては、JavaもC#も機能的には遜色はないものと思われます(Java EEのブループリントであるPetStoreデモが.NETでも実装されていることなどから)。
24時間運転については、仮想マシンの信頼性(特にガベージコレクタ)による所がありますが、これは簡単に比較するのは難しいです。実績からすればJavaが一日の長があると思われますが、定量的な比較がないので結論付けることはできなさそうです。
ケーススタディ1
2004年に開発し2005年に運用開始したシステムがある。10年間の運用を想定しており、現在までに運用中に随時機能改修が行われてきたが、それに伴い扱うデータが増え、性能マージンが狭まり、2010年に計算機の更新および増設を行うことになった。
- 2004年当時の計算機、OSは、
Wintelアーキテクチャ
CPU: Intel Pentium4/Xeon 3GHz前後
OS: Windows XP/Windows Server 2003
- 2010年現在の計算機、OSは、
CPU: Intel Core i7/Xeon 3GHz前後
OS: Windows 7/Windows Server 2008
なお、ここではあえてOS自体を替える想定は外している(Windows ServerをLinuxに替える、等)。これを入れたら比較以前にC#が土俵の外に出てしまうため。
C#で開発していた場合
2004年は、VisualStudio .NET 2003でのC#1.0/.NET Framework 1.1です。
2010年現在の計算機・OSでは、.NET Framework 1.1はサポート対象外なのと、VisualStudio .NET 2003自体もメインストリームサポートはEOLで延長サポート(セキュリティアップデート)のみなので、開発には耐えられない状況です。選択肢としては、アプリケーション開発/実行基盤を以下2つの候補に移行するものとなりそうです。
- VisualStudio 2008/C#3.0(C#2.0)/.NET Framework 3.5(2.0)
- VisualStudio 2010/C#4.0/.NET Framework 4.0
前者は、EOLが2013年の予定で、ケーススタディシステムの運用期間である2015年まで持たない。一方、後者は2010年途中にリリースされるもので、十分な評価・検証ができない。
なお、C#言語自体もバージョンアップ毎に言語仕様もどんどん追加され、C#1.0から随分と変わっている。標準ライブラリも、新たにWPFやWCFが追加されている。移行にあたっては、どれをどこまで取り入れるかといった開発規約からの見直しが発生することになる。方針としては、
- 消極的アップデート:C#3.0, 4.0/.NET Framework 2.0, 3.0, 3.5, 4.0の環境は使用するものの、アプリケーションの記述はC#1.0/.NET Framework 1.1の範囲で留め、新しい仕様・機能は極力使用しない
- 積極的アップデート:C#3.0, 4.0の仕様を取り入れ、.NET Framework 3.5/4.0の機能を使用する
が考えられる。後者はほぼスクラッチ&ビルドになってしまうので、コストは甚大だ。前者は、修正のないモジュール(DLL)はバイナリのまま使用できるのであれば、現実的なコストで対応できる。ただし、改修については開発規約等で使用範囲に縛りをかけるが、コンパイラではチェックできないので、レビュー等での検証が発生する。
なお、C#1.0/.NET Framework 1.1用にビルドしたDLLを、バイナリそのままで.NET Framework 2.0以降で使用できるのか、確たる判定ができていない。Microsoftのサイトでも、バイナリ互換が可能との記述を見出すことができていない。
追記)参考資料として、.NET Framework 1.1から.NET Framework 3.5への移行作業について記載された資料
Javaで開発していた場合
2004年は、Java SE 5.0(JDK1.5.0)がリリースされた年ですが、開発にはJ2SE 1.4.2, J2EE 1.4を使用していたとしてケーススタディを進めます。
2010年現在、J2SE 1.4.2はEOLを迎えているが、有償のサポート契約(Java SE for Business support)では2018年まで延長される。(EOLとEOSLの違いが理解できず、EOLなら2013年)
が選択肢として挙げらる。
前者であれば、移行についてはアプリケーション側には課題はありませんが、基盤となるJ2SE, J2EE実装が新しいOSに対応できているかが課題となる。保守契約での対応だが、アプリケーションでの回避のための修正が発生せざるを得ないこともある。
後者であってもJ2SE 1.4.2/J2EE 1.4で作成されたJavaクラスはJava SE 6/Java EE 6でもバイナリ互換で動作できるため、非互換機能を踏んでなければバイナリのままクラスを使用し続けることができる。非互換についてはアプリケーションの改修が発生する。
http://java.sun.com/javase/ja/6/webnotes/compatibility.html
程度の問題だが、Sunは今までJavaのバージョンアップについては、互換性を最優先にしてきているので、Microsoftの新機能提供優先に比べて安定性は高い。
たとえば、EJBは2.0から3.0でまったくといってもいいくらいプログラムの書きっぷりが変わっているが、Java EE 6(EJB3.1)でも、旧来のEJB 2.0のバイナリをデプロイして実行することができるようになっている。
開発環境は、2010年現在最新のNetBeans 6.9/Eclipse 3.5ともにJ2SE 1.4、Java SE 6.0に対応できるため、開発ツールに問題はない。
Javaは、5.0でジェネリクスをはじめ言語仕様が大きく追加されたが、バイナリレベルでは影響のないイレージャ方式を採用している。もっとも言語仕様に着目すると、不満足な仕様という声がよく聞こえるが、互換性を最大限追及した結果の決断だったことがこの比較の観点では評価できる。極論すれば、コンパイル時の警告を除けば、ジェネリクスがなかったことにもできる。
一方、Javaによる開発で問題になりがちなのは、オープンソースなライブラリ・フレームワークを多用しているケースである。バージョンアップ時には、これらがどこまで対応しているかがコストに影響することがある。
C#とJavaの比較について調べて思ったこと
まじめに比較するには、同じ程度JavaとC#とプログラミングしてみるしかないと思います。が、そのようなドキュメントが実はきわめて少ないということに驚きました。言語なので主観が入ることは否めませんが、あまりに主観ばかりな比較というのも・・・。
日本語では残念ながら見つからず、英語でのよく検討されている比較記事
http://www.25hoursaday.com/CsharpVsJava.html
類似点、似て非なる点、異なる点と3つの観点にグループ化され、各要素がコード付きで比較されています。印刷すると100ページ近い超大作です。
なぜC#を選ぶか
聞きまわった範囲ですが、以下の要因によると思われます。
C#について調べてみて実は・・・と思ったこと
C#について思っていたことが幻想だったと知ったことのメモ
Javaでのオープンソースなライブラリ・フレームワーク多用
開発効率が上がるのは確かですが、保守効率を悪化させかねない問題もはらんでいます。採択の検討時に、保守効率が考えられていればいいのですが、現実は保守効率が考えられているとは思えない節があります。
ソフトウェア開発の体制が、開発時期にのみ請負う(=責任を負う)場合、
開発効率>保守効率
との力が働きます。
たとえば、Javaには標準でlogライブラリが搭載されていますが、世の中は猫も杓子もlog4jを使っています(少なくてもプレゼンスは圧倒的)。確かにlog4jは便利ですが、保守効率を下げても使うほどの優れものとも思えません。特に、log4jにcommons.loggingに、と組み合わせていけば、複雑度が上がってきます。
C#に関する調査メモ
これからエンタープライズシステムの開発にC#を使用する場合に検討しておくべきことのメモです。
GUI
.NET Framework 1.0からあるWindows.Formと、.NET Framework 3.0から追加されたWPF(Windows Presentation Foundation)の2つがあります。これらは別のライブラリ体系なので、アプリケーション開発にあたっては、どちらを使用するか決める必要があります。
WPFを使うなら、まともな開発環境が整ったVisualStudio2010でないと厳しいようです。また、WPFの開発経験者は少ないので、トレーニングコストも見ておく必要があるでしょう。プロジェクトの画面設計・実装のガイドラインやコーディング規約もWPFに合わせて整備しなくてはなりません。
Windows.Formでいく場合、Windowsのクラシックスタイル(という言い方でよかったか?)のGUIとなる点、グラフィックスハードウェアを活用できないので描画にCPU負荷がかかる点、ペイント系処理が遅い点、を許容する必要があります。
データベースアクセス
データベースアクセスに関する.NET Frameworkのサポートは、混乱しつつ発展中、という状況です。ORMについては.NET Frameworkの機能を使うのは時期尚早かもしれません。
- ADO.NET(SQL文をアプリケーション側で記述する)
- .NET Framework 1.0から(1.1、2.0で改良あり)
- ADO.NET TableAdapter(DBスキーマからWizardで生成したヘルパ機能)
- .NET Framework 2.0(VisualStudio2005の便利機能?)
- LINQ (LINQ to SQL)
- .NET Framework 3.5から
- ADO.NET Entity Framework
- .NET Framework 3.5 SP1から
といったものがあるようです。
ここで、気になるのが、O/Rマッピング技術に含まれるライブラリが2系統存在していることです。LINQ to SQLとEntityFrameworkがそれです。また、なぜ、同時期に似た2つの機能がリリースされているのか、ということです。
これについて、いくつか気にしておくべき文書があります。
- InfoQ記事「LINQ to SQLは本当に終わりなのか?」
- InfoQ記事「LINQ to SQLをオープンソースにする必要性」
- InfoQ記事「LINQ to SQL、次のステップ」
- InfoQ記事「.NET 4.0におけるLINQ to SQLの変更点」
Microsoftのロードマップを推測で云々してもしょうがないですが、現時点では、これらライブラリが将来も確固として継続していくのか不透明感があります。