torutkのブログ

ソフトウェア・エンジニアのブログ

エンタープライズシステムの開発言語選定の一考察(C#とJava)

アーキテクチャ設計の一部に、プログラミング言語の選択があります。選択に関わるのは仕事では10年振り(うん? ちゃんと数えると13年か・・・)です。3月から下調べを開始して、可能な限り公平に。
もちろん人間の判断なので、主観が大きく関与せざるを得ません。特にプログラミング言語は、パラダイムの選択になるので。

前提の明確化

技術選定にあたっては、前提を明確にしておかないと、果てしない議論に陥ってしまいます。

ここでは、開発対象をエンタープライズ・システムとします。エンタープライズ・システムは、開発期間よりも運用(保守)期間が数倍(たとえば、開発1年に対して運用10年といったことも珍しくない)になります。また、システム化範囲も昔に比べて増えてきており、その分作成されるアプリケーション規模(機能量)も大きくなります。
また、運用(保守)期間では、随時機能の変更・追加が行われる想定とします。
システムは地理的に分散して運用されます(いわゆる本店・支店・工場、等)。
システムは24時間運転されます。
システムはWeb前提ではありません。

比較のポイント

運用期間を通して、技術が安定して存続していることが最大のポイントです。運用期間が長くなれば、ネットワーク機器・計算機・OS・ミドルウェアなどは当初のモデル・バージョンが入手できなくなり、更新を余儀なくされます。また、運用期間中に処理能力向上の必要が生じたときも同様に新しいモデル・バージョンにならざるを得ないこともあります。そのとき、開発したアプリケーションを載せ替えるために支払うコストがどれだけになるかが選定のポイントです。

バイナリ互換>ソース互換>ソース修正

の順になります。

オンライントランザクション、データベース連携、分散システムについては、JavaC#も機能的には遜色はないものと思われます(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つの候補に移行するものとなりそうです。

前者は、EOLが2013年の予定で、ケーススタディシステムの運用期間である2015年まで持たない。一方、後者は2010年途中にリリースされるもので、十分な評価・検証ができない。
なお、C#言語自体もバージョンアップ毎に言語仕様もどんどん追加され、C#1.0から随分と変わっている。標準ライブラリも、新たにWPFWCFが追加されている。移行にあたっては、どれをどこまで取り入れるかといった開発規約からの見直しが発生することになる。方針としては、

  • 消極的アップデート: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年)

  • 有償サポートで延命を図る
  • Java SE 6.0 (JDK 1.6.0)に移行する

が選択肢として挙げらる。

前者であれば、移行についてはアプリケーション側には課題はありませんが、基盤となる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の比較について調べて思ったこと

まじめに比較するには、同じ程度JavaC#とプログラミングしてみるしかないと思います。が、そのようなドキュメントが実はきわめて少ないということに驚きました。言語なので主観が入ることは否めませんが、あまりに主観ばかりな比較というのも・・・。

日本語では残念ながら見つからず、英語でのよく検討されている比較記事
http://www.25hoursaday.com/CsharpVsJava.html

類似点、似て非なる点、異なる点と3つの観点にグループ化され、各要素がコード付きで比較されています。印刷すると100ページ近い超大作です。

なぜC#を選ぶか

聞きまわった範囲ですが、以下の要因によると思われます。

  • 今まではVC++VBで主に画面を伴うアプリケーション開発をしてきたので、今Windows OS上でアプリケーションを開発するなら、C#を選択する。その際、Javaは選択肢にそもそも上らない。Javaはサーバーサイドのもの、あるいはGUIが遅い、ださい、と思い込んでいる。
  • VisualStudioから離れられない、離れるのはいや。
  • プロパティがお気に入り(日本語でC#の良さを語っている人は大抵この主張)
  • Windows以外のOSで動くアプリケーション開発はしないと思っている。
C#について調べてみて実は・・・と思ったこと

C#について思っていたことが幻想だったと知ったことのメモ

  • Microsoftなので、C#からネイティブライブラリを非常に簡単に呼び出せる仕組みがあると思っていたが、実はWindowsのネイティブライブラリを呼ぶのが簡単ではない
    • 純粋にC言語のライブラリ(extern C 宣言されているもの)は簡単に呼べるが、C++のクラス、メンバー関数を呼ぶのは大変。C++/CLIでいったんラップしないといけない。C++亜種の別な言語を覚えたくはない。
  • JavaGUIを酷評しているので、高度なGUIがあると思っていたが、実はしょぼい
    • Windows.Formは、レイアウトマネージャや2Dグラフィックス、画像処理機能がない、描画性能はGDI+なので遅い。WPFを使うとSwing並みに高機能になるしSwing同様DirectXを活用するので速くなるらしい(新たな課題もいくつか持ち込まれるが・・・)
  • ドキュメント化コメントはXMLで書かねばならない(タグが面倒)。またJavadocに比べて機能が少ない
  • CORBA(IIOP)はなかった(これは、やはり・・・という程度)
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の機能を使うのは時期尚早かもしれません。

といったものがあるようです。

ここで、気になるのが、O/Rマッピング技術に含まれるライブラリが2系統存在していることです。LINQ to SQLとEntityFrameworkがそれです。また、なぜ、同時期に似た2つの機能がリリースされているのか、ということです。
これについて、いくつか気にしておくべき文書があります。

Microsoftのロードマップを推測で云々してもしょうがないですが、現時点では、これらライブラリが将来も確固として継続していくのか不透明感があります。

  • LINQ to EntityとLINQ to SQLの違い
    • M:N関連、エンティティクラスの継承、複数テーブルから1つのエンティティを構成、の3点ができる(LINQ to Entity)、できない(LINQ to SQL
ネットワーク通信