変更に強いWeb-MVC

Railsのコントローラについて、しっくりこない点があった。たとえば、下記のようなコード。

class ExampleController < ActionController::Base
  def show
    @data1 = ExampleModel1.find params[:key1]
    @data2 = ExampleModel2.find params[:key2]
    @data3 = ExampleModel3.find params[:key3]
  end
end

これだと、ビュー側で @data3 の表示が不要になったときに、コントローラのコードをいじる必要が生じる。厳密にはいじらなくてもよいが、いじるかどうか検討する必要は生じる。変更に弱い、ということだ。

ビューがモデルを直接参照していれば、そうはならない。本来、MVCではビューがモデルを参照するのが当たり前。WebアプリのMVCモドキでも、そうするメリットがあるのだ。

結局、コントローラの仕事は「モデルの更新、ビューの決定」のみに留めるべきだと思う。モデルの参照はビューの仕事。


モデルの変更や出力に関わるバリデーションをコントローラで行うのも、変更に弱いやり方だろう。たとえば(必須項目が漏れているなどの)モデルの更新に関わるものであればモデルに任せればよいし、(表示ページ番号などの)出力に関わるものであればビューに任せればよい。コントローラがバリデーションすべきは、更新対象となるモデルや、出力処理を任せるビューを決めるためのパラメータだけだ。

実際には、そのようなパラメータはほぼ使われないだろう。更新対象となるモデルや、出力を任せるべきビューは、アクションごとにおのずと決まるはずだ。つまり、コントローラでバリデーションすべきパラメータはまずない、ということだ。

TDDになじめない

ここ数日、TDDするかどうかの判断基準とは何か考えていた。結局、TDDしたほうがコードが早く完成するのならTDDすべきだし、そうでないならTDDすべきでないという結論に落ち着いた。

ぼくの場合、TDDしないほうが、コードが早く完成する傾向にあると思う。神経質なので、一度テストを書き始めると、完璧なテストケースを作らないと気が済まなくなる。そして、完璧なテストケースとは何かを考え始め、わけが分からなくなってしまう。コードはいつまでも完成しない。

もちろん、完璧なテストケースは、TDDのテストとは別のものだ。それは知っている。ユニットテストを書く段階で、与えられた期間などのリソースを考慮し、必要十分なテストを書けばよいだけの話なのだ。

頭ではそう理解できているのだが、いざTDDしようと思うと、気持ちが完璧なテストケースのあれこれに傾いてしまう。やはり、TDDはぼくには向いていないのだ。


久々にTDDについて考えてみたのは、TDD Boot Camp(TDDBC) - TDDBC仙台03/課題を読んだからだった。

たとえば課題1は、TDDしなくても、ぼくは特に不安なく開発できる。ぼく以外にも、そういう人は多いだろう。

だが、課題1の適切なユニットテストとはどういうものかと考えると、これがなかなか難しい。ぼくが身につけたいのは、TDDのスキルより、限られたリソースの中で必要十分なユニットテストのテストケースを書くスキルだ。数をこなすしかないか。

HTMLエスケープのみで済むコンテキストにおいてだけ、動的出力を許すのはどうか

前回の日記で、コンテキストに応じたオートエスケープ機能をもつテンプレートエンジンに期待する旨を書いた。そうしたテンプレートエンジンは、すでにいくつも存在するが、メジャーにはなっていないようだ。少なくとも、Rubyではめぼしいものがなかった。

考えてみると、さまざまなコンテキストで動的に文字列を出力しようというのが無茶なのかもしれない。発想を変えて、HTMLエスケープのみで済むコンテキストにおいてだけ、動的出力を許すことにしてはどうか。

その前提からは、以下のコーディング規約が導き出せる。

  • クライアントサイドのロジックは、関数呼び出しや値の代入部分も含め、すべて静的に書く
  • クライアントサイドのロジックに渡したい値は、任意のHTML要素の属性値として出力する

URLの出力については、テンプレートエンジンのヘルパーメソッド経由でのみ許可するのが無難だろう。パーセントエンコーディング漏れがなくなるし、スキームのチェックもできる。

「結局、規約かよ」と思われるかもしれないが、「SQL文の実行にはプリペアド・ステートメントを使うべし」という話だって、つまりは規約の話なのだ。DOM Based XSS「対策」だって、エスケープ漏れを防ぐには、何らかの規約を設けるのが現実的だろう。

こう考えてくると、コンテキストに応じたオートエスケープ機能をもつテンプレートエンジンの必要性は薄くなる。メジャーになっていないのは、これが理由かもしれない。

プロフィール
Web開発者。現在の関心事はシステム品質の改善(特に性能効率性と保守性)。JAPAN MENSA会員。
カテゴリ別アーカイブ
記事検索