近頃、Microsoftの技術スタックにはさまざまな流れがあり、開発者は取り残され、どの技術に注力するべきか迷っています。さらに、MicrosoftがSilverlightような技術を公式に非推奨にせずに、ゆっくりとなくなっていくのに任せているため、さらに混乱を引き起こしています。ほとんど知られていないドキュメント、".NET Technology Guide for Business Applications"をひもとくのがひとつの解決方法です。このガイドは今年のはじめにリリースされ、Microsoftの技術の方向性やどのような記述を使うべきでないかを教えてくれます。
この記事では読者の皆さんがMicrosoftと関連する技術を探索するための良きスタート地点になるでしょう。
(クリックして拡大)
SilverlightとFlashからすぐに卒業しよう
WinFormsやWeb Formsのような古い.NETの技術はまだ居場所があります。しかし、SilverlightやFlashのようなRIAコンテナはもう終わりです。次の図の通り、MicrosoftはSilverlight 5の10年のライフサイクルを待ちたいと思っていないようです。2015年の終わりまでに、RIAコンテナを閉め出したいと思っています。
(クリックして拡大)
ハイエンドのアプリケーションでは、完全なネイティブアプリが好ましいです。ローエンドでは、HTML5の能力が向上すると考えられています。どちらに進めばいいかは明示されていませんが、技術の選択については次のように書かれています。
- ネイティブアプリケーションへ移行する場合、どのようなWindowsデバイスでもネイティブにXAML/.NETをターゲットにすることで既存のスキルを活用し、さらには既存のコードを再利用できます。移植可能なライブラリを使うことでバイナリを異なるプラットフォームで共有することもできます。
- ブラウザベースのHTML5アプリ向けには、Microsoftは最新の標準に準拠したデバイス向けにアプリケーションを作成するためのツールやフレームワークを提供します。SilverlightはHTMLと相互運用性があるため、順次移行することができます。
モバイル
Windows 8ストア向けの3つの等価な選択肢
過去、MicrosoftはWindows 8ストアアプリの開発に特定の技術を推奨するのを嫌がっていました。この傾向は今もかわりません。.NET/XAML、C++、JavaScript/HTML5からどの技術を選択するのかは、その開発者の好み次第です。
このような状況をふまえた上で、MicrosoftはC++は性能が良いと見なしています。再利用性はあまり考慮されていません。なぜなら、3つのプラットフォームはどれもWindows PhoneとWindowsディスクトップでコードとリソースを再利用できるからです。
Windows Phone向けネイティブオプション
Windows Phoneで推奨されているのは、.NETとC++です。ここでもC++は性能上有利です。しかし、開発者が得意な方を選ぶのが良いとされています。
Windows PhoneはPhoneGap/Apache Cordovaと互換性がありますが、まったく言及されていません。おそらく、PhoneGapは小さなデバイスにおいて.NETやC++とくらべ貧弱な性能しか出ないと見なされているからでしょう。2013年のBuildカンファレンスでは、性能は最も重要なトピックであり、ユーザビリティやビジュアルデザイン、OS統合などのトピックを押しのけていました。
モバイルウェブ: Web Forms以外
すべてのモバイルデバイスで動作するウェブベースのソリューションの選択肢はたくさんあります。Modernizerを使ったASP.NET MVCが最も基本的な推奨技術です。この技術を使ってSingle Page Application (ASP.NET SPA)を作るという選択肢もあるでしょう。MicrosoftはSPAを技術というよりデザインパターンだと考えています。KnockoutとBreezeもライブラリとして薦めています。
CRUDスタイルのアプリケーションを素早く作るにはLightSwitchも選択肢に入ります。LightSwitchはHTMLの描画をほとんど操作できませんが、開発者はさまざまなスクリーンサイズに合わせて自力でレイアウトする必要がありません。
ASP.NET Web Pagesは4番目の選択肢です。Razorのシンタックスのおかげで、PHPやクラシックASPに似た開発経験を提供してくれます。
古いASP.NETレンダリングツールキットであるWeb Formsは言及されていません。未だに開発が続けられており、理論上、デバイスに固有なHTMLを描画する能力もあるものの、実際にはWeb Formsは実力を発揮できません。Web Formsが出力するHTMLとJavaScriptが非効率的で、さらにview stateは簡単に携帯端末のネットワークコネクションを圧迫してしまいます。
サービス
多くのアプリケーションは外部のデータストレージや処理に頼っているため、サーバサイドの開発は引き続き重要です。Microsoftがこの分野で現役であると考えている技術は6つあります。
第1の選択肢: ASP.NET Web API
Microsoftによれば、新しいプロジェクトのデフォルトの選択肢はASP.NET Web APIであるべきです。RESTパターンに従い、"Akamai、Windows Azure CDN、 Level3など"のインターネットキャッシュに互換性があるサービスを開発するときに便利です。
Web APIを使う場合、開発者はODataに着目するといいでしょう。ODataはRESTエンドポイントの公開形式とJSONを標準化します。
第2の選択肢: WCF
特定のトランスポートプロトコルやメッセージフォーマットに依存しないため、WCFはWeb APIよりも柔軟な選択肢だと考えられています。例えば、TCPや名前付きパイプを使ったバイナリメッセージで高い性能を得るという使い方があります。欠点は、WCFは扱いにくいということです。特に、JSONやSOAPベースではないフォーマットの場合は使いにくいでしょう。
WCFはRPCスタイルの通信を念頭に置いて、企業で使われるために設計されました。一般公開されるRESTスタイルのデザインパターンも実現可能ですが、その場合は、WCFは望ましい選択肢ではありません。
ODataを使ったWCF
CRUDスタイルのサービスレイヤを開発するときにWCFを使いたいのならWCF Data Servicesを使うのがいいでしょう。ASP.NET Web APIを使ったODataライブラリを使い、Entity Frameworkも使えます。
Workflow Services
Workflow ServicesはWindows WorkflowとWCFの統合です。すでに内部でWindows Workflowを使っている場合にのみ、利用するのが良さそうです。Microsoftはほかの使用理由を示していません。
SignalRを使った双方向通信
.NETベースのクライアントを使っているなら、WCFはしっかり調整された双方向通信の選択肢を多数提供します。しかし、.NETとウェブベースのクライアントの両方をサポートしたいなら、SignalRがいいでしょう。
Microsoftによれば、SignalRは"数百万ユーザ"までスケールできるそうです。ウェブクライアントはWebSocketsを使うのが推奨されていますが、必要であれば、自動的にロングポーリングのような古い方式に切り替えます。
SignalRはa .NETクライアント向けのライブラリを提供するので、ウェブやネイティブクライアントがサービスを共有できます。
LightSwitch、その他のODataプロバイダ
MicrosoftがどのくらいODataを愛しているかは言い尽くせません。WCFとWeb APIのODataについてはすでに言及しましたが、それだけではありません。ODataはLightSwitchクライアントでも使えますし、LightSwitchのサーバサイドでも素早くサービスレイヤを開発するのに使えるかもしれません。
MicrosoftによればLightSwitchにはコーディングが必要ないものの、柔軟性を失います。
中小規模のビジネスアプリケーション向けガイダンス
Microsoftは中小規模のビジネス向けのガイダンスを次のように書いています。
- 完全な早さと市場投入時間の短さ
- 生産性と低コスト
- 簡単に使い始められる
- 市場の製品とのコラボレーションと統合
- クラウドの俊敏さとコスト低減の機会
普通の日本語に変換すれば、"素早く、安くすること"です。
中小規模事業者向けウェブアプリ
きれいでないCRUDスタイルのアプリケーションを素早く作る場合は、Microsoftは引き続き、LightSwitchを推奨しています。このツールは非プログラマ向けと説明されていました。多くの人はAccessを置き換えるものととらえていました。しかし、この見方は薄れつつあります。というのはLightSwitchはアプリケーションを素早く作りたいIT部門向けのツールとして提供されているからです。
次はWeb Formsです。Web Formsは未だに新しいプロジェクト向けに推されています。MicrosoftはWeb Formsを、簡単に使えるLightSwitchと複雑なASP.NET MVCの中間に位置すると見なしています。リッチなデータグリッドなどの特徴はまだ企業内部アプリケーションとして適しているのです。
ASP.NET Web Pagesは言及されていますが、わずかです。レンダリングをWeb Formsよりも制御したいのなら、ASP.NET MVCがいいでしょう。しかし、Microsoftは学習曲線が長いことを注意しています。
Windowsディスクトップ向けアプリケーション
MFCやATL/WTLのようなC++ベースのGUIツールキットはすべてリストから外れています。一方、.NETのオリジナルのUIツールキットであるWinFormsは未だに有効な選択肢と考えられています。WPFもそうです。両者はデータバインディング、async/await、WCFあるいはSignalRを使った双方向通信などモダンなコンセプトをサポートします。
WPFとWinFormsのどちらを使うかについてはいくつか考慮する点があります。
まずは難易度です。熟練の開発者であったとしても、WinFormsはWPFよりも遥かに簡単です。WinFormsはとても単純なデータバインディングを使い、クラシックなMVCやMVPを使って開発できます。一方、WPFを使うには複雑なデータバインディングフレームワークを理解し、MVVPパターンを正確に適用しなければなりません。また、WPFをうまく使うには、リソースディクショナリ、コンバータ、ICommand、XAMLのテンプレートエンジンの知識が必要です。
Windows PhoneやWindows 8ストアをターゲットにしているのなら、XAMLの使い方を学ばなければなりません。したがって、この場合はWPFを使ってプラットフォームをまたがってコードを共有できるようにしておくのがいいでしょう。
WPFの柔軟な描画エンジンはWinFormsよりもニッチなアプリケーションを開発できます。しかし、コストはかかります。たいていの場合、WPFアプリケーションはWinFormsアプリケーションよりも性能が悪いです。
LightSwitchはおそらくウェブクライアントで利用できるもの以上を提供しません。したがって、選択する理由は特にないでしょう。
クライアント-サーバは避けるべき
Microsoftが"クライアント-サーバ"というとき、データベースと直接接続するアプリケーションを指し示しています。これが未だに一般的なパターンであることはMicrosoftも認めていますが、彼らは新しいプロジェクトには3層の設計をして、クライアントとデータベースの間にサービス層を挟むことを推奨しています。こうすることで、拡張性が増し、ファイアウォールやその他の障害物をくぐることができます。さらに、データベースドライバが使えないプラットフォームへアプリケーションを移植することもできます。
"モダナイゼーション" - Windowsディスクトップを去る
Microsoftはディスクトップアプリケーションを"モダナイズ"するためアドバイスをたくさん提供しています。ほとんどはアプリケーションをほかのプラットフォームに移植する方法についてのアドバイスですが、中にはWindowsディスクトップを去るつもりのない開発者にも役に立つアドバイスもあります。
- Model-View-ViewModelデザインパターン(MVVM)を使う: Microsoftのクライアントプラットフォーム(WPFを含む)はMVVMを使うと簡単にアプリケーションが開発できます。状態と振る舞いを表示からしっかりと分離できるので、きれいでメンテナンスしやすいコードを作成し、簡単に複数のデバイスに共有できます。
- クライアントのロジックにポータブルクラスライブラリを使う: .NETのポータブルクラスライブラリを使うことでディスクトップWindows Storeアプリ、Windows Phoneアプリのような複数のプラットフォーム間でバイナリを共有できます。ポータブルクラスライブラリを使ってクライアントロジック実装することでマルチプラットフォームのアプリケーションを簡単に実現できます。
- ユーザエクスペリエンスをモダナイズする: 今日のエンドユーザが要求するコンセプトはデスクトップ向けの.NETのでの最新のイノベーションによって実現できます。"fast and fluid","authentically digital","do more with less"というようなデザイン原則はXAMLのデザインにモダンなUIを使用し、アニメーションを慎重に使い、非同期プログラミングを活用することで既存のディスクトップアプリケーションに適用できます。
- ビジネスロジックをサーバへ移動する: 2層のアプリケーション(クライアント/サーバ)の場合、新しいデバイスに展開するのは難しいです。ビジネスロジックをサービスへと分離し、ほかのデバイスやフォームでも再利用できるようにしておくのがいいでしょう。
- クラウドへの拡張: Windows Azureはクラウドへビジネスロジックを移行するためのたくさんのソリューションを提供します。クラウドサービスへロジックを移動すると既存のソリューションの弾力性と拡張性が改善し、複数のデバイスで利用できるようになります。
AndroidとiOSでの.NET
Microsoftは複数のパートナーとともにモダナイゼーションを実現するべく動いています。
- XamarinはC#のコードをWindows、Windows Phone、iOS、Androidデバイスで共有できるようにします。基底のAPIへのアクセスを提供し、仕立てられたビューを作成できます。また、デバイス間でクライアントロジックを再利用できます。
- ITR-MobilityのiFactrとMonoCrossはC#で企業向けモバイルアプリケーションをメジャーなモバイルプラットフォーム向けに構築するためのソリューションを提供します。Abstract UIやEnterprise Data Synchronizationのようなサービスを提供し、デバイスをまたがったビジネスアプリケーションを提供します。
- Art in SoftのMobilize.NETはレガシなアプリケーションをウェブやモバイル、クラウドといったモダンなプラットフォームへ移行するソリューションとサービスを提供します。ランタイムなしで既存のソースコードを新しいコードへ変換します。
- Citrix Mobile SDK for Windows ApplicationsはLOB Windowsアプリケーションをモバイル化するリッチなツールキットを提供し、タッチ操作しやすい新しいアプリケーションを書いて中央のサーバ(Citrix XenApp/XenDesktop)で実行できるようにし、Citrix Receiverを使ってモバイルでバイスからアクセスできるようにします。
追記: MicrosoftがXamarinとMonoCrossを積極的に推しているという事実は、MicrosoftがMonoの作者たちを訴えるのではないかという長く言われてきた噂が噂に過ぎないことを明らかにしているでしょう。
大規模なミッションクリティカルアプリケーション向けのガイダンス
大企業のミッションクリティカルアプリケーションの場合は、コストや生産性ではなく複雑さの管理とサービスの品質にフォーカスが移ります。これらのガイドラインはデータ駆動アプリケーションやCRUDアプリケーション向けではありません。そのようなアプリケーションを作る開発者は小規模/中規模向けのビジネスガイドラインを使うほうがいいでしょう。大規模なミッションクリティカルアプリケーション向けのガイドラインは多くの連携部分とサブシステムで構成されているシステム向けです。
企業でのウェブアプリケーション
この点ではMicrosoftの態度ははっきりしています。ミッションクリティカルなウェブサイトではASP.NET MVCを使うべきだということです。アーキテクチャ上の唯一の問題はSingle Page Applicationデザインパターンを使うかどうかです。
Web FormsやWeb Pagesは使うべきではありません。コントロールがきかず、MVCスタックがテストできないからです。その結果、クオリティ・オブ・サービスに制限がかかります。
企業向けディスクトップアプリケーション
より小規模のアプリケーションと同様、Microsoftは推薦する技術としてWPFとWinFormsを挙げています。さらに、Win32やMFCを使ったC++も選択肢に挙げています。C++の使用はMicrosoft Officeに匹敵するような大規模で工期の長いプロジェクトで推奨されています。
企業でのWindowsストア/Windows Phone
この分野の推奨事項についてMicrosoftは"‘新興のアプリケーションパターン'の章で記載されている推奨内容と同様"ということ以上は何も語っていません。自信があるという状態ではなさそうですが、これらのプラットフォームを完全に捨てているというわけでもなさそうです。
Patterns and Practices
Microsoftガイドラインの最後の20ページを製品についての説明を脇において、Patterns and Practicesに着目しています。
制御の反転
Microsoftは驚くべき時間を依存関係の挿入(dependency injection)と制御の反転(inversion of control)の説明に費やしています。9つの異なる制御の反転のコンテナを示しています。このうちの大部分はMicrosoftが関係していない、コミュニティプロジェクトです。示されているフレームワークの多くは実際はIoCのコンテナであり、依存関係の挿入のフレームワークではありません。
Microsoftがコンポジットルート(DIパターン)を推奨しているのか、サービスロケータ(IoCコンテナパターン)を推奨しているのか判然としないため、依存関係の挿入と制御の反転の間で混乱が起きており、フラストレーションがたまります。Mark Seemann氏が言うとおり、両者は根本的には正反対のものだからです。
Microsoftは"単一責任の原則(Single Responsibility Principle,SRP)"を使って依存関係の挿入を正当化します。彼らによればSRPによって、たとえば、コンストラクタに15の依存があるクラスが出来上がります。これらの依存を"分離する"ため、コンストラクタから依存を引き離し、IoCコンテナを使って依存を注入することを推奨します。
またMicrosoftはアスペクト指向プログラミングを使って、間接化のためのレイヤを追加し、依存性を注入することを推奨しています。
境界のあるコンテキストと複雑さの管理
複雑さを管理するために、Microsoftは数ページを使って、"境界のあるコンテキスト"とはどのような概念なのか説明しています。この概念はEric Evans氏の著書に基づいています。アプリケーションを小さなパーツに分けて共有する部分を限定的にするというのが基本的な考え方です。下図は、異なるバックエンドと共通のUIを持った4つの分離されたスタックで構成されているアプリケーションの例です。
(クリックして拡大)
この分野でのMicrosoftの推奨事項は多くの点で合理的です。境界のあるコンテキストを使うことで、ミッションクリティカルな部分を特定し、その部分にコマンドクエリ責務分離(CQRS)やドメイン駆動設計(DDD)のようなよりコストがかかるパターンを自動テスト付きで導入する一方、付随的な部分はより軽量なCRUDスタイルのアプリケーションにします。もちろん、レガシコードもひとつのパーツにして分離し、ゆっくりと置き換えを行います。
通信と防腐
境界のあるコンテキストの間で情報を共有する場合、Microsoftは可能な限り、非同期メッセージングを使うことを推奨しています。別のパーツが動作不良を起こしたとしても、各パーツが独立して動作できるからです。単純なシナリオの場合、名前付きパイプとMicrosoft Message Queuesは簡単な選択肢です。より複雑なシステムの場合はサービスバスが必要でしょう。MicrosoftはWindows Server Service Bus、Windows Azure Service Bus、NServiceBusに言及していますが、どれかを特別に推奨してはいません。
境界のあるコンテキストが公開するサービスは防腐レイヤで守られている必要があります。パブリックな関数を守るパラメータチェックと同様に、防腐レイヤは不正なメッセージから基底にあるデータストアを守ります。やってくるメッセージを検証し、必要な変換を行い、不正なデータが処理され保存されるようにします。このような一連の処理は普通の.NETのコードで実現できます。しかし、ビジネスルールが頻繁に変わる複雑なシナリオの場合は、MicrosoftはルールエンジンとBizTalkのような統合プラットフォームを使うことを推奨しています。
レガシコードの移行
レガシコードを処理する第一歩はファザードを作ることです。このファザードは永続的でスケーラブルなキャッシュのようなモダンな技術を使い、古いコードがどのようなパターンを作っていても隠蔽します。レガシなコードは回避され、ファザードは新しいサービスレイヤにリダイレクトします。
結論
MicrosoftはSilverlightと.NET Remoting以外の.NET向けのすべてのネイティブ、ウェブ、通信フレームワークを支持しています。また、いくつかのシナリオにおいてはC++とJavaScriptも奨めています。VB 6やクラシックASPのような古いプラットフォームはもはや言及されていません。いまだに古い技術を使っている企業は可能な限り早く移行したほうがいいでしょう。
また、予想通り、引き続き依存関係の挿入の重要さを強調しています。特にASP.NET MVCとEntity Frameworkで顕著です。BizTalkは一度は死んだ技術だと思われていましたが、オンサイトとクラウドを統合しようとする企業が現れたために新しい命が吹き込まれました。
著者について
Jonathan Allenは2006年より、InfoQで記事を書き、現在は.NETのリードエディタ。ニュースや記事の執筆に興味のある方はjonathan@infoq.comへ連絡してほしい。