命名:IsExistsを考える
IsExists多すぎ問題
昼の仕事でIsExists...というメソッド名を目にする機会があった。
気持ちはわかるものの、Existは動詞なので、be動詞は不要だよねという話をしつつ、折角なので記事を書いてみようと思う。
be動詞じゃなくてもboolを使ってもいい
説明するのに良い例がないかと思って考えてみたら、Contains がLinqだしちょうどいい気がした。
docs.microsoft.com
動詞か助動詞始まりの場合、be動詞は付けなくてもboolにしていいんだということを理解してほしい。
Has なんかも.NETではなじみ深いboolを返すbe動詞始まりではない表現ではないだろうか。
助動詞でよく使うのはCan...だが、日本の中学に通っていた方は思い出して見てほしい。
”be able to”は”can”と同じように使える
この”able”は、動詞や名詞の終わりに結合すると、「~できる、可能にする」という形容詞に変身させることが出来る。
例えば、 Available
は利用可能の意味になる。
形容詞なので、みんな大好きbe動詞であるIs
が使い放題なのでこのableを末尾につける業をお勧めしていきたい。
.NET Framework => .NET Core vNext を考える
前提条件
.NET Coreへのマイグレーションは.NET CoreがGAになった当初から課題としてある。
今年はMicrosoftもDeveloper Dayが開催されていて、そこでマイグレーションの話題のSessionがあった。
同じ意見な部分も多くありつつ、私が所属しているチームの開発パワー等の都合もあり、そのまま取り入れられないものもあったため、2022年2月現在の考えを整理するためにもまとめていく。
マイグレーションの前準備
プロジェクトファイルをSDKスタイルに変更する
スライドだとこの項目は2番目に来ているが、自分がマイグレーションを行う際には、package Reference形式に変更するのはSDK形式に変更する業と同時に行う。
package Reference形式は結局のところ、csprojに変更を入れる必要があるため、変更後の確認やレビューを考えるとSDK形式にしてしまったほうが筋が良い。
また、ここでpackage.configの削除も行う。
ここで注意しなければならないのは、プロジェクト構成のすべてをcsprojが握っていた旧時代と違い、SDKスタイルだと配下のフォルダは基本的にProjectにincludeされること。
そのため、Projectからファイルを除外だけしてSCM管理外にしていない。といったファイルが含まれる可能性がある。
チーム開発で且つ、チームメンバーのパワーにグラデーションがあるチームだと起きがちなので、コードレビューでガードしていきたい。
スライドを見てもらうとわかるが、推移的な参照の説明があるのが素晴らしかった。
Package Referenceにした際に、ついでに無駄な参照は破棄しておきたい。
Build&駆動検証
SDKスタイルにした際に不要な参照が入ってしまう問題があるため、Buildと駆動検証を必ず行う。
駆動検証は、もしテストがあるならば楽が出来る。
依存しているnuget Packageが.NET 6で利用できるか確認する
ここが、Activeな.NET6のプレイヤーじゃないと些かややこしい部分かもしれない。
.NET6 のApplicationは、
- .NET6
- .NET5
- .NET Core 3.1
- .NET Standard2.1
- .NET Standard 2.0
のpackageを参照できる。
つまり、性能さえ気にしなければ、.NET Standard 2.0に上げてしまえば、駆動は可能となる。
なので、ここでいう利用可能は、最低でも.NET Standard 2.0版のpackageが存在しているかどうか。という観点になる。
これがもし存在していれば、移行が可能。
もし存在していなければ、移行先packageの選定、もしくは自作が要求される。
依存している非nuget packageの.NET6で利用できるか確認する
ここは、開発組織のパワーによってはチーム間で調整が必要なので大変かもしれない。
nuget package化のススメ
非対応が、サードパーティーのdllを購入している。という場合はまた別の話になるが、そうでない場合……例えば別チームの作ったpackageを読み込んでいる。という場合はnuget packageでの管理を検討したほうが良い。
csprojを見れば利用しているpackageのバージョンが自明な状態であることはソフトウェアを開発するにあたって結構大事なので。
マイグレーションの実行
Target Frameworkを.NET6に変更
.NET Coreで開発している人にはおなじみのTFMを変更しよう業。
変更すること自体は容易だが、.NET Frameworkからの激しいジャンプの場合、依存しているProjectもすべて.NET6で利用可能なTFMに変更する必要がある。
また、Windowsやxamarin等はTFMがプラットフォーム固有のものになるため、注意が必要。(Application Modelの項で別途補足する。)
依存packageを.NET6で駆動可能なバージョンにアップデート
あくまで、「なるべくジャンプが少ない状態」を選択し続ける必要がある。 ダイナミックにコードレベルですべて変えるのは、テストコードを書いて仕様を保護した後にしたい。
Application Model対応
マイグレーションにおいて、おそらくこれが本丸なため、後述する。
Build&駆動確認&deploy方法再構築
これが完了すればマイグレーションは完了となる。
.NET Core 3.0にて非対応となったApplication Model
.NETにはBCLと呼ばれる基本クラス群と、Application Modelと呼ばれるApplicationのRailの部分が存在する。 ここではRailとなるApplication Modelのうち、.NET Core 3.0にて非対応となってしまったものを列挙する。
.NET Core3.0以降も対応しているApplication Modelの移行
Windows Form / WPFの移行
Windows互換性packageの参照を追加する ※ TFMはnet6.0-windowsにする必要がある。 www.nuget.org
マイグレーション時にやることは比較的シンプルに収まっている印象。
ASP.NET MVCの移行
スライドにもあるが、ASP.NET MVCはBreaking Changes が大量にあるため、移行が難しい。
ASP.NET Core MVCは 3.0未満の時代は.NET Framework でも開発が可能なため、一度ASP.NET Core Mvc 2.2に刻んでいくかどうか問題
- ASP.NET Core MVCは 3.0未満の時代は.NET Framework でも開発が可能なため、一度ASP.NET Core Mvc 2.2に移行
- Build&検証
- ASP.NET Core 3.1 に移行
- Build&検証
- ASP.NET Core 6 に移行
- Build&検証
というマイグレーションパスがスライドでは示されていた。
ここは、通常は非常に良いアイディアだなあという気持ち。
一方で、Owinを本格利用していない場合、ASP.NET Core Mvc 2.2がそもそも最難関なので、OwinのStartupを利用していない場合、最早ここは.NET6へのジャンプのほうが筋が良いように見える。
.NET Core3.0以降で対応していないApplication Modelの移行
WebFormの移行
なるべくWebForm Project内に存在しているコードを別のProjectに移す
※ この際、System.Webに依存しているProjectは作成しないよう注意。 HttpContext等への依存が切れないとやる意味がなくなってしまう。
マイグレーション先として採用すべきApplication Modelの判断
個人的には、
- ActiveではないApplication(なるべく塩漬けにしたい) =>
Blazor Server
orASP.NET Core Razor Pages
orASP.NET Core MVC
- ActiveなApplication(積極的に変更や改善を行いたい) =>
ASP.NET Core MVC
説を推して行きたい。
Blazor Serverが移行先として挙げられることが多いがなぜMVCなのか???
.NET Core3.0以降で対応していないApplication Modelについては書き直しを要求される。
また、上記はどれも、本来必要な技術を高度に隠蔽することで、本来必要であるべき技術の学習コストを省き、短期的な生産性を上げるという思想のApplication Modelである。
一定の成果を上げたという意味で大変素晴らしいという尊敬の念はあるものの、Webに関するApplicationを開発する以上、Webに関する知識や技術から遠ざかることで、例えばWebFormの開発者はWebFormしか書けないプレイヤー、しかもWebFormについても熟知していない状態になってしまう風潮が強かった。
ActiveなApplicationについては、今一度Blazor Serverを採用してWebFormと似た書き味に行くよりは、ASP.NET Core Mvcへのマイグレーションを素直に行うほうがプレイヤーの確保、及び育成面で筋が良いように感じる。
一方で、なるべく塩漬けにしたいApplicationについては、Blazor Server が選択肢に入ってくる。
特に塩漬けのようなperformanceを考えなくて良い場面であれば、AWSのツールサポートが.NET6時代の今ならある程度受けることも可能である。 aws.amazon.com
WCFの移行
gRPCに関してはMicrosoft特有の技術でもなければ、高度に隠蔽するApplication Modelでもないため、個人的には推奨したい。
一方で、WCFの移行先がgRPCというのは、WSDL(SOAP)形式からの乗り換えであればワンチャンありそうだが、HttpRequest + REST APIに近しいデザイン(ステートレス、URL Resourceベース等々)をしている場合、gRPCにしてしまうと、Client側がgRPC対応のカロリーを消費する必要が出てくる。(Protocol Buffersからリバース生成できる仕組みが各言語にあるとはいえ、対応はそれなりに時間が必要。)
これを踏まえると、
HttpRequest
+REST API
に近しいデザインのエンドポイントを提供している場合 =>ASP.NET Core Mvc(WebApi)
- WSDL(SOAP)形式からの乗り換えである場合 => gRPC
説を推して行きたい。
SQL Server Management Studio でInsert文を自動生成する(たぶん何億番煎じかくらいだと思う)
テストコード用のテストデータを手組しているという話題
永続化層込のTestを行っている場合、container上でテストコードを動かす際に、セットアップでテストデータを投入する必要がある
「パワーのあるチームは、適切にマスクを行った検証用Databaseのサンプルが常にcleanな状態に存在していて、そのDBからデータ同期をすれば良いのだろうか??? 」 と想像しつつも、自分のチームはチーム外のコードベースやテストを触ることがままあるため、そこまでの運用ジャンプを相手に強いようとすると、付いてこれなくなる恐れがある。
一方で、
「SQL書くの大変だ!」
って話すらあるのも理解できる。
「テスト用の永続化層instanceのcontainerを上げてから、データ入れてって、Management Studioからリバース生成するだけちゃうんちゃうん?」
と聞いたところ、意外とやり方を知らないという空気だったので自分の記憶整理も兼ねて書いてみることにした。(もうちょっと洗練した仕組みに出来たほうがいいんだろうと思いつつ、運用を他チームにお願いする以上、ジャンプの大きさは、頑張れるギリギリを狙うしかない。というのが、近年での学びとしてある。)
SQL Server Management Studio でInsert文を自動生成していく(SSはSSMS v.18で取得しているため、バージョンの新旧によっては、メニューの配置変更があるためあらかじめ留意する事)
スクリプトの生成ウインドウを表示させる
SSMS上でServerへの接続完了後、Insert文を自動生成したいDatabaseを右クリック => タスク => スクリプトの生成 を選択し、スクリプトの生成ウインドウを表示する。
Insert文のリバース生成を行う
スクリプトの生成ウインドウで、[ 次へ ] をクリック => オブジェクトの選択画面に切り替わったら [ 特定のデータベース オブジェクトを選択 ] を選択
Insert文をリバース生成したい対象のテーブルを選択し [ 次へ ] をクリック => スクリプト生成オプションの設定画面に切り替わったら [ 詳細設定 ] をクリック => スクリプト作成の詳細オプションを表示する。
[ スクリプト作成の詳細オプション ] の、[ スクリプトを作成するデータの種類 ] を [ データのみ ]に変更して [ OK ] をクリックする。
ここまで来たら、あとは任意の設定で[ 次へ ]を押して行けば、Insert文のリバース生成が完了する。(どこに吐き出したいかはお好みで。)
エンドポイントのリソース設計と404について考える
ステータスコード論争があったのでいい機会なので纏めてみる
個人的には、管理するエンドポイントによってWayが異なることは勘弁してほしいという気持ち。
前提条件
URLはリソースである。
404について考える
case1: hoges/
=> hogeのコレクションリソースを返す
case2: hoges/1/fugas
=> hoge=1にぶら下がるfugaのコレクションリソースを返す
case3: hoges/1/fugas/1
=> hoge=1にぶら下がるfuga=1のリソースを返す
としたときに、
case2, case3については、指定したIdリソースがない場合、404。
case1 はリソースのId指定が含まれていないので200 ないし 204
というのが個人的な感覚。
大体、物言いが、開発外から付く
よくあるのが、コレクションリソースを返すというケースで404にしてくれって話を貰うパターン。
URLがリソースである以上、requestを投げる側でコントロールが出来ないものに関しては400系を返すべきではないというのが個人的な感想になる。
基本的に使いやすければOKでは?
基本的に使いやすければ良いのでは?というアドバイスを先輩から頂いた。 githubのApiの定義をひとまず見に行こうかなという気持ち。
ボーイスカウトルール
野山をきれいにする
久しぶりにプログラマが知るべき97のことを読む
個人的に好きなのはボーイスカウトルールの項
コードをチェックアウトした時よりもチェックイン後の方が美しくなるようにする。
これは、自分のためのみならず、他人のために必要なこと。
お互いにコードを美しくしていくことが必要。
たとえ自分が書いたコードではなかったとしても、美しく直す必要がある。
もちろん、すべてを完璧にする必要はない。
インクリメンタルな改善を入れていけば良い。
ボーイスカウト活動をするにあたってテストコードが必要
リファクタリング a.k.a. コードクリーンアップは絶え間なく行う必要がある。
絶え間なく行うために何が必要か?
仕様を保護してインクリメンタルに変更をいれる必要がある。
仕様を保護して安全に変更を入れるためにはテストコードが必要だ。
ファッショナブルにリファクタリングと言う前に泥臭くテストコードを書こう。
我々は別におしゃれのためにテストコードを書くわけではない。
一発でいいコードが書けないから、絶え間なく改善を行うためにテストコードを書くんだ。
テストコードをインストールするためにはまず書き続けられることが大事
ジャンプが大きすぎてやめてしまっては元も子もないので注意して対応を行う。
あらゆる機能のインストールについても同様で、開発組織がインストール速度に耐えられなければ破綻してしまうことに注意が必要になる。
VisualStudio2022でようやく改行設定が試験的に追加されて嬉しい話
今まで「不要な改行✂」みたいなくそコメントを人間がわざわざコードレビューで書いていたんですが、ようやく.editorconfigで制御できるようになりそうで嬉しい。
が、試験段階だからなのか、まだコードクリーンアップには対応してないみたい。
dotnet formatには対応しているようなので、しばらくはこちらに頼る予定。