ロジックを分けましょう

20 12月

本日はちょっとしたホラー話です。警告しても警告してもなくならないエンドレスな物語。

エターナル フォース ブリザード!

効果: プロジェクトは死ぬ

ビューとモデルの分離

みなさん、ちゃんとビューは薄く作っていますか?ビューやコントローラーにロジックを詰め込んじゃっていませんか?

まして、.aspx/.cshtml/.php/.jsp なんかのHTMLテンプレート部分にロジックを書いちゃっていませんか?

まあ、「ビューとモデルの分離」と言われてわかる人は、そりゃ分離しますわね。問題は、言われても何のことかわからない人。というか、わかってない人がプロジェクトに含まれている場合。

HTMLテンプレート中のロジック

ASP.NET MVCのRazorエンジン、便利ですね。軽くもう、C#スクリプトですよこれ。C#書き放題!

とかやってて後から泣くわけですね。例えば、以下のようなコードを書いて。

@using System.Linq;
@{
    ViewBag.Title = "
ホーム ページ";
}

<p>
@{
    Sample[] items = ViewBag.Items;
    var i = items.First();
    if (i != null)
    { 
        <span>@i.Name</span>
    }
}
</p>

「Itemsの先頭要素が、あれば表示したい」というつもりのコードです。つもり。LINQに慣れた人なら気づくと思うんですが、Itemsが0要素の時、このコードは例外を起こして止まります。よく見るあれ、

アプリケーションでサーバー エラーが発生しました。

あれが起きます。

問題はこの行ですね。

    var i = items.First(); // Firstは、要素がないとき例外発生

正しくは、FirstOrDefaultって書かないとダメです。

さらに悪いことに

「こんなのすぐに気づくよ」と思うかもしれません。しかし…これの悲劇は…

以下のような状況を想像してください。

  • このコードは自分で書いたものではありません
    • バージョン管理をしていて、updateをしたときに、他人の書いたコートが混ざったものです
  • ローカル実行では問題が出ませんでした
    • たまたま、自分の使っていたテスト データは要素0なデータが含まれていませんでした
  • ところが本番でだけエラーが出ました
    • 再現条件がわからず、小一時間悩むことに
    • そしてしばらくしてから気づく「あれ、私こんなコード書いたっけ?」

とかいうのが起こりうる現実。

問題と対策

Firstメソッドの仕様がどうとか以前の問題で、テストの自動化の習慣がないことが最大の問題ですね。あと、レビューをきっちり回すプロセスの欠如。

そして、テストの習慣がついてたら、cshtml中にロジックを書くのなんてもってのほか。

GUIのテストは難しい

一般に、GUIはテストがしにくいです。Coded UIテスト(プログラムでで「ボタンを押した」とかのイベントを起こして、ユーザー操作を疑似的に再現してUIのテストをする手法)なんかもなくはないですが。多くの場合、手作業確認になります。

前述の、「0要素の場合の確認が漏れ、本番環境でエラー」なんかも、手作業確認だから漏れるわけです。

あくまでテンプレート

cshtmlなどのファイルは、あくまでHTMLを生成するためのテンプレートです。

デスクトップ アプリに関してはこのAdvent Calendarでもちょこっとだけ話しましたが、以下のような、データ バインディングという仕組みを使って、UIからデータを分離します。

UI側の記述では、「ここにXを表示したい」というような印だけを入れておきます。

cshtmlでも、やるべきことは同じで、この手の印にあたるコードだけを書くべきです。

となると、書けることは限られてきます。cshtml中に残るC#コードは以下の程度なはずです。

  • 一覧表示のためのforeachステートメント
  • プロパティ参照(@item.Xなど)
  • ごくごく簡単な分岐(例えば、0の時だけフォントや文字を変えたいとか)

そしてテストを

分離したデータの側は、単体テストを掛けれるはずです。掛けなきゃいけません。

今回話したようなちょっとしたコードですら、後から悩まされるわけです。テストなしで自信を持って書き換えられますか?

性能問題が出ているコードで、「たぶんここ直せば改善しそう。コード直すのは30分ほどなんですけども。テストがないからちょっと触れないですねぇ。」というもよく聞く話。納期が近づいてからでは遅いんです。最初から、テストを書く習慣を身に着けておかないと。

「スピードが大事なんでテストをしっかりやる時間がないんです」とか言って手を抜いて、あとから苦しむことになって、結局余計に時間がかかるなんてのもよく聞く話。よく聞く話で、よく警告話も耳にするのに、なぜか繰り返される悲劇。

まとめ

  • テストがないと後で死ぬ
  • ビューにロジック書くとテストできなくて死ぬ

Visual Studioを使ったテストの話も、残りのAdvent Calendarのどこかでしましょうか。

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。