ハード寄りの現場のプロトタイプ開発で、Windowsデスクトップアプリを捨てて、Webアプリに本気で移行してみた。


# 体験記

## 簡単な自己紹介

　私は工場のラインや検査装置関係で、制御ソフトの開発の仕事をしています。
　今まで、制御用のファームウエアや、Windowsデスクトップアプリケーションを中心に、開発を経験しました。

　今回はデスクトップアプリの話をスタートとして、書きたいと思います。
　※私が知っていたりざっくり調べている範囲で書いているので、間違っている部分が多くあると思います・・・遠慮なく指摘ください。

## 今までの開発環境(Windowsデスクトップアプリ)

　そもそもC/C++/C#での開発、という話をしている時点で「相当レガシーなシステム」の面倒を見るというのが前提になります。職に就いてから7年になりますが、結構様々な環境で、BtoBを相手に開発していきました。

　「ああ、なんか懐かしいな」みたいな開発環境が揃うような気がしますが、これでもVisual Studio 2008が最盛期の時期から考えると「現役」でした。Qiitaが出来る前の開発環境がとても多いかもしれませんね。コメントも簡単に書いておきましょう。

### ネイティブC++に限定すると・・・

- **Qt** ：C++では、未だに現役の人が多い環境ですね・・・

- **MFC** ：いまだに開発している人がいるのか？と思うのですが、独特ながらも、ポインタ操作が高速で、それなりのGUIが作れるのが魅力的ではありました。Windowsで独自の数理アルゴリズムを開発するときにはいまだに使う人、結構います。OpenCV、DirectXなどとの相性も良いので、これらを簡単に使いたい場合にも〇かな。

- **Borland C** ：知り合いが愛用しています・・・これを超えるほど使いやすくてフレキシブルなGUIで、イベントも自由に管理出来るようなものはないと・・・。少なくとも、1990年代では最も元気があった開発環境ではなかったでしょうか。

- **Win32** ：さすがに最近は、これで開発しているという声はあまり聞きませんね。Windows独自機能が要求されたときに、この部分の知識があるとすごく役に立ちますけどね

### .NET Framework系列だとこんな感じですかね。

- **C++/CLI** ：今の仕事では、なぜかこの環境で全ての開発を行なっています。正直ゾッとしています、確かに使っている彼らの言い分は分かるのです。それは、C++をC++っぽく、Linux GCCやBorlandでやってたような記法と同じように書けて、勉強コストが少ないって感じるという気持ちはよく分かります・・・　~~マネージドコード(CLR拡張)なんてなかったんだ・・・~~

- **Windows Forms** ：前職は、これがほぼメインだった気がします。現場作業者って基本まともにプログラミングが出来ない方がとても多いのですが、Windows Formsを使えば多少それが緩和されます。作業工数の面でも良いし、Windows Formsに多少バグはあるものの、メンテナンス性も良いです。一応.NET Frameworkは2029年まで使えるし、ライセンス的にも緩いことから、なんだかんだここから離れられていない人、たくさんいそう。 

https://qiita.com/dev-kuri734/items/8aa1adc094f7009463fa

- **WPF** ：確かにWPFやUWPのようなフレームワークはMicrosoft的にはビジネスとしては失敗した感覚はありますが、XMLで画面を書き、MVVMを使ってデータバインドをするという考え方は優れていて、現在のモダンプログラミングへの足掛かりにはなるでしょう。「絶対座標系がいらない、JavaBeansの思想に近い**（※お前は、いつの時代の話をしているのか。）**画面配置が出来る」と思って、それなりに感動しました。上記のフレームワークは画面サイズ対応に悩まされますが、WPFであればそこから解放されます。


### とまあ、これだけの色々な開発環境があるわけですが・・・

　正直言うと、**「Windowsアプリケーションの開発は限界がある」**と思っていました。


### GUIの限界

　最もそれらしい悩みとしては、「**ブラウザのようなGUIが作れない**」というところ。

　よくある理由である「リッチなアプリ」というのはもちろん一つなのですが、もっと致命的な理由としては、WPFのところで触れたように、基本古いデスクトップアプリは大半が**絶対座標系**で表現されているということです。これは非常につらいことで、デスクトップの解像度によってGUIの配置を常に考えなくてはいけないということを意味します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281173/1c2f7391-ce82-be1d-226e-bfb61e430b62.png)

　具体的に書くと、こんな感じで部品が、「X座標に200, Y座標に100にPanelを置いて」、とか「PictureBoxは親のPanelから(30,40)のところに置いて」とか、そういうような処理をいちいち書いているのです。

　これは、**プログラミングの知見があまりない人にとっては、とても使いやすい仕様であることを指摘したいと思います。** したがって、これが悪いというものではなく、こういう需要がかなっている場合もあるということです。

　それは、「欲しい部品がどこか、欲しい制御装置がどこか」を考えるメカ設計者の立場になれば容易に分かると思うのです。彼らは、図面を頼りに、部品の位置を決め、そこに配置します。そこに至る過程は絶対座標系とそれを組み合わせた相対座標系でのみ表現されるということに異論はないでしょう。そして、その位置がぴったり同じところに来るということが、品質的に正しいことを認める必要がありますから。

　ところが、こういう思考は、ソフトウエア開発の世界になると危険な部分がありますよね。
　例えば、画面が小さくなった時にバグが起きるかもしれない、とか、最小ディスプレイでも最大ディスプレイでも挙動が同じでないといけない、とか。**「そういった仕様」は、プログラミングに知見がない人には、理解しにくい概念です。**

　統計で考えるのであれば、メカ設計者の部品設計には必ず「平均」「公差」という概念があります。これは平均的な位置には必ず推定値が来ることを保証するためです。ところが、最小のディスプレイか最大のディスプレイか、というのは「平均」「公差」ではなく**「再現条件」**です。その再現条件がどんな条件であっても、動くことを想定する必要がありますが、メカの設計では「決まりきったものを作らなければ」「無駄にコストがかかる」ことが分かっているので、どうしても動きにくいわけです。

　ちなみに、Windows FormsやWPF、UWPでこの流れは多少緩和されていますが、今のブラウザほど綺麗に整備されているとは言い難いとは思います。
(~~Web業界でも、稀に崩れたレイアウトを堂々と出してくるサイトあるのが厄介なんだよねえ・・・）~~

### モデルという概念がなく、開発環境として便利にサポートされていない

　詳しい説明は省きますが、昨今のフレームワークは、ロジック部と表示部は基本的に分離することが大前提となっています。

　当然ながら、過去の遺産となっている開発環境には、こうした発想はありません。それは、自由度を高くするという意味合いにおいては、非常に良いことですが、ルールがなく無法地帯になりやすいというデメリットもあります。それを無理やりコーディング規約にしよう、ということもありますが、それは場合によってはチームの効率を下げることもあり、あるいは独善的になることもあり、導入にはチームとして色々考えていく必要があります。

　コーディング規約は所詮「取り決め」なので、上司に意見を通して、ごねれば、通るかもしれませんが、それよりも致命的な問題は**モデルという概念がないこと**です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281173/587bbef1-2b66-5aa5-47aa-4396eb3d4a62.png)

　モデルがないと、どうなるか？というと、ロジック部と表示部を好き勝手移動することになるので、ロジック部のプログラムなのに、突然設定画面の値がポーンと放り込まれていたりするわけです。

　例えば、上記みたいにテスト採点ツールがあったときに、THの値を画面から設定して、それを使って判定をかけたいと思います。これを実装するとき、**「データバインドを使って解決しましょう」**とか、**「モデルを定義して、ロジック部に"TH"という変数を書いておいて、それを画面に反映させましょう」**という思考が出来れば、それはこの悩みを理解しているといえます。

　・・・ところが、先ほどの選択肢(WPF, UWP以外)では、これが出来ないです。理由は**「THというフィールドを、GUIに置かないといけないから」**です。そして、これが出来なくてきつくなる場合というのは、実際の設計でも怏々としてあります。それは、**顧客の要望は常に変わるもの**だからです。

　単に"TH"というのを表示して欲しいという要件であれば、これはこのままでいいんです。ところが、顧客というのは大体そうはなっていなくて、打合せをした日になって突然**「THってとこ、実は国語用と数学用とあって分けているんですけど。あと出来れば誰でも作業できるようにしたいから、THというところは弊社で決めさせて」**とか言い出すわけです。

　そこで、まあ初回の打合せだし、そのくらいの変更ならいいっかって思って、国語用と数学用のフィールドを作って、THも二つ用意したロジック部も見直すわけです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281173/505aeadb-3c41-ff44-6002-e9da2250695a.png)

　そして、次の打合せで、**「いや～実は、2つのフィールドとは言ったんですけど、留年間近の生徒は追試をしないといけないから二つくらい欲しいんだよね。あとランクでS,A,B,C,Fとかつけてくれないと、システムとしてまともに使えないんだわ」**とか言ってくるわけでして・・・。

　そしてそして、細かい変更を修正して、また細かい修正をしたことで別の部分に不具合を生んで、最終的に原因不明の不具合を持ったままリリースみたいな、悲しいことが起きてしまうわけですよ・・・。

※営業の仕方が悪いとか、技術検討の段階で技術者の意見を十分に入れなかったとか、人間の問題のこともあると思いますけどね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281173/65ed4309-9361-723b-fd65-b938b3d47a79.png)

　こうした問題を「モデル」を使えば解消できるわけです。モデルさえあれば、あとは既に機能として出来上がっているライブラリなどを使って、閾値の画面を勝手に作ってあげたらよいのです。そうすれば、画面を作ることを考えなくても良い、もしくは画面を変えたいと思ったとしてもちょっとした微修正で済むということがあります。

　一見いいこと言っているように見えるのですが、こういうことを言うと(それなりに知識のある)C++/C#のGUI設計に慣れた人からこんな声が挙がってくるはずです。**「ライブラリの挙動は信用にならない、それであれば自分で動きを作ってしまった方が確実だ」**と。そして、これ自体は一理ありますし、もしこれが2010年代の初めくらいであれば、便利なフレームワークもなかったので、この意見を無条件に受け入れてたと思います。

　それを思いっきり変えたのが、**jqueryに代表されるWebブラウザ用のライブラリ**です。今ではjqueryを派生したより良いライブラリは多く存在しますが、2010年始めにおいては、jqueryが登場しかけの黎明期であり、不具合も残しながらも少しずつ受け入れられるか受け入れられないか、という状況でした。

　さらに、今でも問題になっていますが、**Internet Explorerの互換性問題**。jqueryに代表されるライブラリがまだ少数派だった頃は(Web業界で中心で仕事していたと思われる人は別として）、Microsoftの中でも「今後流行するだろうけど」という懐疑的な目線があったのかもしれません。　今ではこれなしにはWeb業界が語れないという世界まで進化していますが、そういう状況であればデスクトップアプリを中心に開発していた方であれば、「今のところ無関係だ」と思うのは仕方ないと思います。事実、Microsoftも2016年を最後にInternet Explorerのリリースを終えていますからね。

　実はMicrosoftも2009年にASP .NETの開発に着手し、Visual Studio 2010で初めて対象になり、Visual Studioのアップデートに伴って徐々に改善されてきました。当時から、Microsoftもサーブレットを適用したシステムに関心を持っていたことが伺えますが、(実は今でもその影響が若干残っていますが)度重なる仕様変更により**「正直厄介なシステムでまだまだ色々変わるだろう」**という状況でした。

　そういう意味で、Windowsデスクトップアプリの開発者が、Webアプリを作るということは状況的に考えにくいわけです。まあ、もちろんruby, php, Pythonなどを使うという手もありますが、Windowsの独自仕様なしに仕様作れないことも多いわけでして、特に**.NET Frameworkには大いに助けられているものと思います。**

　そう、彼らは決して悪くはありません・・・。

---

　ただそんなMicrosoftも、近年になり.NET Frameworkから.NET Coreへの移行を進め、最終的には.NET Core 6/.NET Core 8を長期サポートとする計画に動き始めました。

## ASP .NET MVCを勉強しながら、案件に活用して思うこと


　現在の最新版は.NET Core 6で、.NET Core 5は安定版です。ただし、将来的にCore 5はサポートされなくなるので、私がこのまま案件を続けていれば、.NET Core 6を主体にして設計する流れになると思います。

　これは、私が今回案件で試していることに対して大きなジャンプになることを考えています。Windowsアプリで出来ないこと、またはWindowsアプリでは当たり前に出来ていたことを色々試す機会となっていて、よりモダンなシステムが作れることを期待しています。

　実際、ASP .NET MVC 5で作ったプロトタイプを、最近顧客に提示したところ、思った以上に受けが良かったです。やはり、プロトタイプのレベルでも、複雑な機能を簡単に作れてしまう、そしてモデルがあることで容易にロジックと表示部を分けてしまえるということもあり、やってみて良かったなと思います。

　もちろん、Core5→6に移行するにあたって生じる問題点を懸念しておく必要があります。ただ、ASP .NET MVC 5自体は既に2018年でほぼ出来上がっている形であることから、極端に仕様揺れが発生するものはないと思っています。

 ~~MicrosoftがWindows 10移行の次世代のOSを作らなければの話ですが。アップデート程度なら大丈夫だと思う。~~


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281173/b26d5b9b-5009-e5d7-3b6f-349d40ee2fb1.png)

↑　最近作った画面のスクショ。jquery.DataTablesライブラリを使ったことにより、検索やシリアル番号の変更と言った処理をクライアントベースで書いてしまうのがとてもうれしいです。
　同じことをWindows Formsでやることを考えたら、とてもじゃないですけど、工数が何倍にも膨らんでしまうと思います（テストとかも考えるとね）。裏でデータベースを走らせているのもあるし。

　実際、この画面を顧客に見せたのですが、色々な機能をアピールできたし、不明確な運用イメージを明確に出来ました。


　個人的に、ASP.NET MVC 5がうれしいのは、こういうところですね。

- jquery、backbone.js、angularなどのクライアントライブラリが使える。GUIを綺麗にするライブラリも多数あるし、品質も(少なくともWinFormsやWPFより)素晴らしい。


- C++をCLR拡張を使って動かせる。拡張に関する理解がきちんとあれば、どんなレガシーなライブラリでも使いまわせる。

- ASP.NET MVCは.NET Core 5に移行してから、WindowsのサーバシステムであるIIS Expressをオープンソースで動かせるようになった。これは、Visual Studioがない環境でも、簡単に置くことができるというメリットがある。(Windowsアプリだと当たり前なんだけど、Webアプリだとサーバサイドのシステムを別管理しないといけないので、この作業を省略できるのは便利。)

- Dotnet EF Code Firstという仕組みを使って、データベースをSQL文を一切使わずに管理できる。というか、データベース自体がモデルになっているので、出来上がったシステムのまま、モジュールテストにかけてしまうことが出来る。データベースの構文の中身を理解してなくても何とかなる。Windowsアプリでありがちな、ファイル管理などの問題を気にしなくていい(Microsoft SQL Serverに関する知識は多少必要だが)。

- Google Chromeを開いたまま、プレゼンが出来ること！（~~Powerpointも捨てられる嬉しさ~~）
 

　クロスプラットフォーム環境では多少劣りますが、Windows用のドライバでないと動かないハードも多数あるので、Windowsを前提にするシステムなら本当に使いやすいと思います。

## どうやって勉強したのか

　勉強のコストは色々高そうに見えるのですが、元々C++が強ければ、多分大体のものは書けると思うのです。なので、

- HTML、jsonの知識を身に着けること

- jqueryで簡単なプログラムが書けること

- ASP .NET MVC 5を勉強できる教材を持つこと

※udemyのこれが凄く良かったです。（絶賛勉強中）Visual Studio 2013があれば学べます。言語は英語ですが、字幕もあり難しくはないので、コツコツやれば理解出来るようになれると思います！

https://www.udemy.com/course/the-complete-aspnet-mvc-5-course

- (オプション)C++/CLIまたはC++のネイティブDLLの実行に関する理解、Windowsカーネルモードへの理解

　これだけのスキルがあれば、一人で構築できますし、逆にそれがなくても分業出来るので対処しやすいと思うのですよ。Windowsでデスクトップアプリを作り続けてきた猛者なら何とかなります。

　私もまだまだ未熟で、始めたばかりなので・・・
　jqueryのプログラムはqiita、StackoverflowなどのサイトやjsfiddleなどのJavaScript・HTMLのエミュレーションツールを使いながらいろいろやってますが、本当に今まで出来てなかったことを容易に出来ることが出来て、本当に頼もしいです！

https://jsfiddle.net/