※この記事は 2018年 12月に初回投稿しています。
Windows Forms といえば、随分アップデートされなくなった技術ですが、未だに現役バリバリな現場も多いと思います。
(2019/04/16 訂正。「サポートが終了した技術」と書いていましたが、そのような公式発表はありませんでした。執筆者の勘違いだったので訂正致しました。誤解を与えてしまい、申し訳ありません。)
私は福岡で仕事をしていますが、Windows Forms 案件は、まだまだ多い印象です。当分は死滅しないでしょう。2018年に発行された VB.NET や C# の初学者向けの書籍でも、サンプルソースにバリバリ登場している位ですし。
というか、他の Windows デスクトップアプリ開発のプラットフォーム(WPF や UWP)なんて、それ専用の書籍でないと、まずお目にかかれないんじゃないかと言うレベルです。
とは言っても、終わった技術をいつまでも使い続けるのは健康に悪いので、「何とかしないと。。。」と Windows Forms で作成されたプロジェクトを保守しながら、頭を悩ませているエンジニアも多いのではないかと思います。
そういった境遇に悩み、選択肢をいくつか挙げて、試してみました。
自分なりに、「これが一番ベターでは?」という結論までは出しています。
1.WPF or UWP といった Windowsデスクトップアプリのプラットフォーム
WPF は Windows Forms の後継として出てきましたが、どうにも普及率は今一つ。その WPF はそろそろアップデートが無さそうな雰囲気なので、さらにその後継の UWP が選択肢として挙がる事もあるかと思います。
が、WPF・UWP を触ってみた感じ、正直、Windows Forms の移管先として、ベストな選択肢かどうかはかなり疑わしい。
まず、Windows Forms と WPF・UWP は、アーキテクチャが全く違う。
少なくとも Windows Forms ユーザが、これまでの知識や経験をベースにソフトスライディングできるような代物では、決して無い。むしろ、これまでの知識をバッサリ捨て去って新しく1から学び直すぐらいの心構えが必要な場面すらある。
基本、Windows Formsは、画面とビジネスロジックを完全に分離させない事も多いが、WPF・UWP を使う場合、MVVM にて画面とビジネスロジックを分離する事になる。
体感的に、これがかなり学習コストが高い。特に Windows Forms に慣れ切った人は、そのあまりに文化の違いに苦労させられる事も多いんじゃないかと思う。
そして、V と VM をバインドという仕組みで値を結びつける方法を取る事になるが、体感的に、業務アプリの仕組みをバインドだけで何とか出来るかどうかは大いに疑問に思っている。
どういう事かと思うと、業務というのはえてして複雑化しやすい。そして、その複雑さはアプリの画面の複雑さとなって、そのままシステムに反映される。
画面が複雑化する事で、画面と内部の値を自動で結びつける仕組み(バインド)を実装する事が困難なケースが度々登場する。
サンプルソースにて、「ああ。こうすればいいのね。」と簡単な例を見て、「わかったー!」となるかもしれないが、実際のコーディングにあたり、「あれ? この場合はどうするんだ?」という場面に直面すると、解決策を調べるのにえっらい時間がかかったり、言語仕様の深い部分に突っ込むことになったりしたうえ、やたらと複雑な物が出来上がったりする。
というか、自分はバインドだけで何とかするのは途中から止めときました。
頑張れば何とか出来たかもしれないけど、シンプルにするためにバインドを使用するのが目的であって、バインドさせる事で複雑度が向上し、可読性とメンテナンス性を悪化させるより、無理にバインドに拘らない方がいいな、と落としどころを付けました。
個人的見解として、VM → V の直接操作(ピンポイントで V を指定)は当然しないが、抽象化した Vのパーツの参照を VMに持たせ、それに手を加えるのはOKとする、という構造がいいんじゃないかという気がします。
そんな感じで、Windows Forms では悩む必要の無かった場面に色々と直面する事になります。
単に WPF・UWP のみの学習だけでもそれなりにある事に加え、MVVM を実現するために、Prism や Behavior といったライブラリの使い方も学習する必要がある。
また、WPF・UWP は、MVVM を実現できるパーツは揃っていても、それを実現するためのフレームワークは提供してくれていない。
うまく伝わらないかもしれないが、MVC を体現した Rails が、「Rails はこうやって MVC を実現したぜ!」と、プラモデルキットを用意してくれている(最低限の枠組みは用意されている)のに対し、WPF は「必要な部品はあるから、好きに作ってね!」と、ネジやドライバー、板金やカッターといった部品だけが用意されているといったイメージ。枠組が無いので、どんな構成にするかはエンジニア自身の手に委ねられる。(どう作るか悩む場面に直面する。)
ネジやドライバーそのものを作る必要はさすがにないにせよ、昨今の各種フレームワークの優秀さを感じた後だと、枠組みとしてはかなり貧弱な印象は拭いきれない。
Microsoft推奨の構成やデファクトスタンダードになってる構成も無さそうな感じだし、エンジニアが苦労しながら自前で作り込んでいく必要があるんじゃないかと思う。
そこまで高い学習コストや、基盤構築にかかるコストを払ってまで、得るものがあるか?
と聞かれれば、首を傾げてしまう。
Windows Forms から移行したところで、今後の開発工数が劇的に改善されるわけでもなければ、出来る事が増える訳でもない。
むしろ、開発スピードが落ちることだってある。
Windows Forms では簡単に実現出来たことが WPF では苦労させられる場面も結構あったり、実行速度が Windows Forms に劣っていたりと開発者を悩せたりする面もある。
また、長年 Windows Forms を使い続けている現場は、色々と便利なコンポーネントを資産として持っている事も多いと思う。
WPF・UWP に移行すると、恐らく大半はマトモに動かない。ほぼ作り替えレベルの修正が必要になる。Windows Forms と、アーキテクチャが全く違うのがそれに起因する。
学習コストの高さ、基盤構築にかかるコストの高さ、移植の難しさを考えると、別に画面とビジネスロジックの分離にこだわらず、Windows Forms チックな書き方にする選択肢もアリなんじゃないかとすら思う。(あくまで移植の場合に限るけど。ただ、そんな事するくらいなら、Windows Forms 使い続けとけよ、と思ってしまう。)
また、MVVM にする事のメリットとして、「画面とビジネスロジックが分離できる(デザイン担当者とバックグランド担当者の作業を切り分けしやすくなる)」ってのがあるけど、Windows デスクトップアプリにて、そのメリットが十分生かされる場面は、Web 系と比較して極端に少ない。
どういう事かと言うと、「見た目や使い勝手が悪かったら、そもそも使ってもらえない」という Web サービスと違い、企業向けの Windows デスクトップアプリは「どんな劣悪な見た目・操作性でも、使ってもらえる(代替品が無いため、他に選択肢がない)」という状況になりやすい。
ユーザも、「仕事を回すため、仕方なく使っている(別にそのサービスが好きで使う訳ではない)」という意識のため、凝ったデザインや演出の必要性は非常に薄くなり、それらの実装に工数を割けない(割けたとしても利益に繋がらないため、削られる)傾向がある。
そんな感じで、デザインや UI/UX の専門家の出番はなく、ビジネスロジックをゴリゴリ書いてるエンジニアが画面まで作るので、「分離する事のメリット」を最大限に享受できない事も多い。
え? 分離する事でユニットテストがしやすくなる?
はっはっは。Windows Formsを長年使っている現場に、そんな概念ありませんぜ。
「ユニットテストって何?」という話がスタート地点だ。
場合によっては、「疎結合って何?」って所がスタート地点かもしれません。
そこからテストの有効性を説明し、テストしやすいように疎結合を心がけてもらうように開発者に説明し、テストコードを書く工数をプロジェクトに盛り込ませるための説得をし、テストコードを書く文化を根付かせるという、非常に気の長い作業が待っています。
その過程で、勤続年数の長いエンジニアから
「はぁ? 何でこんな風に書かないといけないの? 書きづれーし、面倒くせーよ。」
と反発される事を言われるケースもあるかと思います。
そして、声高に叫ばれる事は少ないが、「分離する事のデメリット」は、きっちり存在する。
言い換えれば、分離せずに密結合なモノリシック構成にするメリットはあって、Windows Forms ユーザは意識せずにそれを享受している。それが無くなった時にどう対処するのがベターか、いい方法を探し出すのに結構苦労する場面も出てくる。
分離する事によって直面する問題に対し、「あれれー? Windows Forms じゃ考える必要が無かった問題だなー。どうしよー。」と悩むのを、時間の無駄と考えるか、成長のチャンスと考えるかは状況次第。
そういった状況の時、勤続年数の長いエンジニアから
「ほらみろ。余計な事してるからだぞ。」
と嫌味を言われるケースもあるかと思います。
それらに加え、現在が WPF → UWP の過渡期と言うこともあって、どちらを採用するか選定が悩ましい問題もある。
UWP は基本 Windows 10 以降でないと動作しない。
Windows 7 がまだまだ現役で動いている現場も多い中、「このシステムは、Windows 7 はサポートしません!」と言い切っても、それが通せる政治力や、端末を全て入れ替えるだけの資金力が無いケースも多いんじゃないかと思う。
そして俺は未だに Windows XP が現役で稼働している現場をいくつか知っている。
んなミニマムな話を例に出さずとも、2017年にランサムウェアが猛威を振るった時、被害に遭った OS にとっくにサポート切れだった Windows XP のパーセンテージがそれなりの数字を叩き出していて、リテラシーの低さに呆れた人も多いと思う。
そんなエンプラ業界が、Windows 7 を簡単に捨てられるか?
個人的には全く思わない。恐らく Windows 7 は、サポート切れから 5 年経っても現役として稼働し続け、そのうちセキュリティ事故により Windows 7 ユーザがまだ多く存在する事を世に知らしめる未来が色々な人に見えているのではないだろうか。
そんな感じで、「壊れていないなら、限界まで使い倒す。」という思想が根強いエンプラ系企業において、古い OS をバッサリ切り捨てる選択を取りづらい事も多い。
なら Windows 7 でも正式サポートされている WPF か? と言われても、そっちはもうアップデートされない(多分)技術だ。
そんな技術を選定する事が良い選択かどうかは疑わしい。
Xamarin にしてネイティブアプリとバックエンド処理を共通化する、といった目的が無い限り、こっちの選択は避けた方がいいんじゃないかというのが個人的見解。
これも個人的見解なんだけど、WPF・UWP と相性がいいのは、型が厳格な C# よりも、静的言語ながらもある程度の緩さがある VB.NETなんじゃないかと思う。静的型付けでありながら、疎結合との相性のよさを見せてくれるという点では、もっと世間から評価されていい言語なんじゃないかと思ってる。
2.Windows Forms を使い続ける
いっその事、Windows Forms を使い続けるというのも、1つの手だと思う。
オープンソース化されたので、今後、面白い方向になっていく可能性は十分あるし、自らで変えていくという方法もアリだ。
個人的に Windows Forms は実用性の高いプラットフォームだと思っている。
だからこそ、こんなにも長く使われているし、アップデートされなくなっても、なお使われ続けている。
規模が大きくなると指数関数的にメンテナンスと拡張が大変になるというデメリットはあるが、
「個人が」
「少ない工数で」
「小規模なアプリを作る」
という状況であれば、ちゃちゃっと作れてしまう手軽さは大きなアドバンテージとなる。
学習コストも低めで、マニュアルを詳しく読まなくとも、直感的に色々とやりたい事が推測できるというも大きい。
個人的には終了させるには惜しい技術だと思っていて、この思想を持ったプラットフォームが後世に出てほしいと思ってるくらい。
「移行の検討すらしない」というのは論外だが、
「移行を検討した結果、コストに対するメリットが見いだせなかったので、Windows Forms を使い続ける事にします。」(なので、予算は次のプラットフォームが出た時用に取っといてね。)
というのは、立派な選択肢の1つだと思うのだが、どうだろう。
3.ASP.NET Core
.NET Core を使い、Web アプリにする。
個人的に、これが一番いい選択肢なんじゃないかと思う。
Windows デスクトップアプリは、今後どんどん衰退していく事が予想されるので、高い学習コストをかけて WPF や UWP を使うよりは、いっそ Web アプリにしてしまった方が未来があるんじゃないかという考え。
ずっと Windows デスクトップアプリをメインでやって来たエンジニアにとって、Web のシステム開発はハードルが高く感じるかもしれないが、WPF・UWP も、それに負けず劣らない学習コストが発生する。(書き手の主観として)
どっちにしても学習コストが発生するなら、より未来が見える方を選んだ方がいい。
Microsoft も力を入れている技術なんで、極めて有効な選択肢なんじゃないかと思う。
あとがき
突っ込み所は多々あるかと思いますが、自分なりに色々手を出し、悩んだ結果、以上のような結論となりました。
ただ、自分は特定の団体に所属していない(フリーランス)事もあり、特定のバイアスはかかってない(少なくとも技術選定の観点では)という点では、それなりに意味のある事は書けたんじゃないかと思う。