ウィリアムのいたずらの、まちあるき、たべあるき

ウィリアムのいたずらが、街歩き、食べ物、音楽等の個人的見解を主に書くブログです(たま~にコンピューター関係も)

画面とプログラムを分けても、コントローラーがないと、テスト&解析しにくい

2005-11-22 21:23:57 | PHP

 前のブログで、PHPで画面とプログラム部分を分けて書く方法(プログラム規約)を書きました。

で、今回は、その具体的例を示そうとおもったんだけど、

 それって、前に書いたブログ、PHPで、別のPHPや画面を呼び出す、あるいはエラー画面と正常画面を切り分ける方法 と、基本的に同じなので、(あとはbunki_cnt.phpで、セッションに値をいれて、その値を画面で表示すればいいだけ)その例は、今回は省略します。
 ホームページかなんかに、まとめたら、そのとき例を書くと思います。

 で、今回は、このやり方(画面とプログラムを分けるけど、コントローラーがない。カオル姫方式)の問題点として、テストしにくかったり、解析しにくいことを、上記ブログの例から示します。




 上記のブログで示した例について、まとめると、こんなかんじです

・ユーザー名を入れる画面を用意する(項目名:username)
・処理するプログラムのPHP(bunki_cnt.php)で処理を行い
   (例にはその部分はありませんが)画面に表示する値を取得、セッションに入れて
   その処理結果によって、headerのLocation指定で、次の画面を決める
     ここでは、usernameがgoodmanなら次の画面(OK.htm)
     そうでなかったら、エラー画面
・表示画面(例はhtmですけど、本来はPHP)では、そのセッションの中身を表示する。




■■ この方法の問題点。
 では、処理部分(bunki_cnt.php)のテストをしましょう。といったときなのですが、結果として、OK.htm,NG.htmのどちらが表示されるので、この両方とも、用意しないといけません。
 今回は処理が簡単ですし、画面も2つだからいいのですけど、これが、複数画面になってしまうと、全部の画面をあらかじめ用意して、で、その画面では、セッション内容を表示できるようにして。。。となったら、テスト負担が大きくなり、結局、全部できてから、流しで行うっていうことになってしまいます。




■■ この問題の改良法(なにもしないようでも、コントローラがいるわけ)
 で、それを防ぐには、どうしたらいいか、つまり、画面を用意しなくても、テストドライバだけで、モジュールテストするには、どうしたらよいか?ということなのですが、これは、
必ず、コントローラーに戻して、コントローラーが、次画面を表示するようにすれば、問題は解決します。

 つまり、上記の例をこのように修正します(太字の部分が修正箇所)
・ユーザー名を入れる画面を用意する(項目名:username)
・画面から、コントローラーを呼び出す
・コントローラーは、画面項目をセットし、処理するプログラムを呼び出す

・処理するプログラムのPHP(bunki_cnt.php)で処理を行い
   (例にはその部分はありませんが)画面に表示する値を取得、セッションに入れて
   その処理結果によって、セッションのnext_URLに表示したい画面のURLをセットする
     ここでは、usernameがgoodmanなら次の画面(OK.htm)
     そうでなかったら、エラー画面
   そして、コントローラーを呼び出す
・コントローラーは、next_URLの値をもとに、headerのLocationで表示画面を呼び出す

・表示画面(例はhtmですけど、本来はPHP)では、そのセッションの中身を表示する。

というかんじで、コントローラーにかならず戻るようにすると、この処理部分のユニットテストを行うには、

・ユニットテスト用コントローラーを作成する。
 そのコントローラーは、入力時のセッションの値をログなりどっかに出力
 出力時のセッションの値をログなりどっかに出力しておしまい
(画面表示はしない。次の画面は、セッションの値を出力しているので、そのnext_URLの値をみて、ただしくセットされているかどうか判断する)

・テストドライバとして、引数をセットして、そのユニットテスト用コントローラーを呼び出して、単体テストする。

・実際の時には、本番用コントローラーにきりかえる。そうすると、next_URLの値をもとに、表示画面へ遷移する。

みたいなかんじで行えます。




 で、この例にかぎらず、というか、PHPの話に限らず、コントローラーっていうのは、なーんにもしてないことも多いんですけど、必ずそこをとおる!というところがあると、便利だったりします。

 で、気が向いたら、このコントローラーを使った、まさにPHPでMVCを実現する方法について、書きます。で、このコントローラーつきのものを、カオル姫-テンさん方式とよびます。
 なぜ、テンがつくのかは、バレーづきの人にきいてください。
 このまえのJTのテレビCMと、
 「かならず、コントローラーにもどす」このコントローラーをセッターに言い換える。
 といえば、延々と、説明してくれる。。はずです。

P.S バレーとは、バレーボールのことで、踊るほうではない。女子バレー好きの人に聞いてね。

 

  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

PHP等で画面とプログラムを分離する(処理結果で画面分け:カオル姫方式)

2005-11-22 17:35:04 | PHP

 実際に、画面とプログラムを分離する際、プログラムの処理結果によって、画面を分けたい場合、

・コーディング規約だけで、特段のことを使わず
・さらに、アジャイルっぽく、テストファーストやモジュールテスト可能で
・もちろん、分業可能なようにするには?

どういう規約にすればいいかについて、書きます。

(なお、「カオル姫」で、このページに来ちゃった人、このページには、カオル姫のCM情報しかないです。>_<! ごめんなさい。CM情報は、このページで、1箇所だけ、リンクになっているところ)。

 この方法、3通りあります。
 1つは、コントローラーを使わないもの
 2つめは、コントローラーを使い、
   コントローラーが次に処理するプログラムや、画面を決める方式
 3つめは、コントローラーを使うものの、
   次に処理するプログラムや、画面はコントローラーが決めるのでなく、
   コントローラーを呼び出す側がきめるもの

 についてです。
 なぜ、3番が必要かは、3番について書くことがあったら、そのとき、覚えていて、気が向いたら書くことでしょう。

 なお、ここでは、以下、省略して
  1番の方法を、カオル姫方式
  2番の方法を、カオル姫-テンさん方式(集中)
  3番の方法を、カオル姫-テンさん方式(分散)と書きます。
 なんで、こんな名前にしたかは、あとで、書きます(このブログの中に書かれることでしょう)。

 今日は、カオル姫方式のご披露です。




 PHPで、プログラムと画面を分ける事は、意味があります。

 それは、デザイナー部分と、プログラマーの作成部分を分けるということもあるし、画面が来る前に、プログラム部分をテストしたり、プログラム部分ができてないとき、画面部分を先にテストできるからです。

 さらに、業務上の要請からもあります。

 業務において、こんなケースが考えられます。
  支払いが
   ・銀行振り込みのときは、何も処理しない
   ・カードのときは、与信チェック
     エラーのときは、エラー画面表示
  その後、なんかいろいろ処理して
  正常のときは、同じ「正常処理」画面をだしてね!

 といったように、エラー画面が出るか、正常画面が出るか分からない(与信チェックしないとわかんない)、かつ、場合によって、処理内容が違う。そして、1つ1つの処理は長い。でも、最終的には同じ画面を出すといったかんじ。

 こういう、処理結果によって画面が変わるとか、ある値によって、処理が違うといったときも、
   1画面1PHPプログラム、
   1処理1PHPプログラム
 にして、分離したいわけです(そーしないと、ものすごい量のプログラムになる)。

 で、どうするか。。。




そのとき、こういうコーディング規約にします。

■■ 画面側(VIEW)
・デザイン部分をあらかじめ作成しておきます。そして、動的に値が変わるところは、なにか、マークを入れておきます。
・はじめに、sessionをスタートさせます。
・セッションの中に、入っている値を表示します。
   項目名1つに、1つの値が入っているときはそのままprint、
   項目名が、複数レコードで、1レコードにいくつかの項目がある場合は、
   foreach(@_SESSION[項目名] as $rec) で1レコードぷん取り出すのを繰り返させ、
     その繰り返しの中で、 print $rec[カラム名] で値を表示する。
・デザイン時、動的に値が変わるところに、マークを入れてもらい、
 上記の書き換えを行う。

■■ 処理側(プログラム部分)
・Viewがクリックされた場合、処理用のPHPプログラムを呼び出す
・そのプログラムでは、画面表示するとき、動的に値が変わるところは、セッションの中に入る
・最後に、さらに処理が続く場合は、headerのロケーション指定で、次の処理を、
  VIEWで表示したい場合は、headerのロケーション指定で、VIEWのPHPを呼び出す

という形になります。




 つまり、イメージ的にいうと、

・プログラムの処理部分と、VIEW部分を、完全にPHPプログラムをわけてしまい、
・クリックしたときには、プログラムの処理部分を呼び出す。
・で、処理中に、表示したい値をセッションに入れて
・最後に適切な(画面表示したい)VIEWをheaderのLocationで呼び出す
・呼び出されたVIEWは、セッションの値を表示する

といったかんじ。




 この例を、先ほどの「業務において、こんなケースが考えられます」と挙げた例で書くと、

・画面入力後、「銀行振り込み・カード振り分け」PHPをForm のActionから呼び出す。

・銀行振り込み・カード振り分けPHPは、
   銀行振り込みのとき、「なんかいろいろ処理して」PHPを呼び出す
   カードのとき、カード処理PHPを呼び出す
 呼び出し方は、この前のブログに書いた、hederのLocationで

・カード処理PHPは、処理をして
   エラーだったら、表示に必要なものをセッションにセットして、
      エラー画面(VIEW)を呼び出す
   OKだったら、「なんかいろいろ処理して」PHPを呼び出す
 呼び出し方は、この前のブログに書いた、hederのLocationで

・「なんかいろいろ処理して」PHPは、いろいろ処理して、セッションに表示内容をセット
 最後に、「正常画面」PHP(VIEW)を呼び出す
 呼び出し方は、この前のブログに書いた、hederのLocationで

・呼び出された「正常画面」PHPや「エラー画面」PHPは、セッションから値を取得して
 それを表示する。

てなかんじになる。




 で、今CMで、これを見える化??したものがテレビのCMで、流れている。

 JTのCMで、バレーボールのやつ(ここ

 このCMで、バレーボールがセッションだと思ってください。

 このボールをカオル姫(菅山かおる選手、一番左上)が受け取って、次々に選手、さらに、工場や、運送のおにーさん、タバコ屋のおじさんがつないでいき、最後に、アタッカーがボールを打ちますよね。

 ここで、アタッカーは、境界、バウンダリになるので、Viewつーか、画面になります。
 その間の人は、ポールをつなぐ(セッションに値を入れる)という処理をしていますよね。
 このボールをつないでいる、それぞれの人が、PHPプログラム。

 つまり、セッションをつうじて、アタッカー(VIEWプログラム)へ、いろいろの人が処理(PHPプログラム)してる。

 で、JTの選手は、竹下さん(一番上4番目の写真)とカオル姫だけでなく、もっといろいろいるけど、ボールがきたのは、たまたま、この2人、つまり、セッションの中に入っている値によって、処理するPHPプログラムが選ばれる。

 で、カオル姫は、竹下さんは知ってるけど、まさか、タバコやのおじさんは知らない。

 つまり、PHPの処理プログラムは、状況によって、次に誰を呼び出すか(複数候補有)は知っていて、ボールによって=セッションの値によって、呼び出す先を決めて、呼び出す(headerのLocationで)てなかんじなわけです。




 ということで、この方式を、このCMからとって、カオル姫方式と、勝手にウィリアムのいたずらが命名しました(一番初めにボールを受けるのが、カオル姫なので)。

 で、次の話は、この具体例を示したり、カオル姫-テンさん方式についてご披露するのですが、それについては、気が向いたときに、またかきます。
 もう時間切れ!なのだ。



  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

PHPで、別のPHPや画面を呼び出す、あるいはエラー画面と正常画面を切り分ける方法

2005-11-22 14:07:20 | JavaとWeb

 きのうのカオル姫方式を披露する前に、その前段階である、headerにLocation指定をすることにより、別画面を呼び出したり、表示画面を切り分けたりする方法について、書いておきます。




■■ 問題

 いま、入力されたら、チェックして、正常なとき、正常画面、エラーのとき、エラー画面を表示したいとします。

 つまり、こういった入力画面があって

<HTML>
<HEAD><TITLE>てすとだぴょん</TITLE></HEAD>
<BODY>
<Form action="bunki_cnt.php "method="post">
    Name:  <input type="text" name="username"><br>
<input type="submit" name="submit" value="実行">
</form> 

(なお、プログラム中、全角の < >は、本当は、すべて半角です)

こんなかんじで、ユーザー名だけ入れます(項目名:username)

で、そのとき
●ユーザー名がgoodmanだったら、こんなかんじで、入っていい画面をだします。
<HTML>
<HEAD><TITLE>あなたは、いい人ですね</TITLE></HEAD>
<BODY>
<H1>入っていいです</H1>
</BODY>
</HTML>

(なお、プログラム中、全角の < >は、本当は、すべて半角です)
この画面をOK.htmとします。

●ユーザー名がgoodman以外だったら、こんな感じで、NG画面を出します。
<HTML>
<HEAD><TITLE>あなたは、わるい人ですね</TITLE></HEAD>
<BODY>
<H1><Font color="red">はいっちゃだめ</font></H1>
</BODY>
</HTML>

(なお、プログラム中、全角の < >は、本当は、すべて半角です)
この画面をNG.htmとします。

 つまり、usernameの値を見て、goodmanのときOK.htmを、それ以外のときNG.htmを
表示する、PHPプログラムを書くということです。
 このプログラムを、bunki_cnt.phpとします。




■■ 方法
$_POST['username']の値をチェックし、header("Location:URL名改行改行");で飛ばすことになります。
つまり、プログラム(bunki_cnt.php)は、こんなかんじ

<HTML><BODY>
<?php

	if( $_POST['username'] == "goodman" )
	{
		header("Location:OK.htm¥n¥n");
	}
	else
	{
		header("Location:NG.htm¥n¥n");
	}
?>
</BODY></HTML>

(なお、プログラム中、全角の < > ¥は、本当は、すべて半角です)

そうすると、ユーザー名の値によってきりかわります。

 改行コードは2つ、URLの末尾に必要です。

 同じサーバーの中のファイルを見ているので、NG.htmのように、ファイル名しかかいていませんが、そこに http://www.yahoo.co.jp のようなURLを書いてもOKです。そのサイトを表示します。




■■ ここからいえること

 昨日の方法だと、画面を処理によって切り替えることはできませんでしたけど、今日のこのLocationをつかうと、

 画面入力
  ↓
 処理を行うPHPプログラム
   ・実際の処理を行う。
   ・セッションに画面表示すべき値をいれる
   ・Locationで、次に表示する画面設定(場合によって、飛び先が変わる)
  ↓
 表示画面用PHP
   ・セッションから値を取り出し、画面表示(のみ)

 という感じで、複数のいろんな画面に飛ばせることも可能です。
 カオル姫方式の基本は、このやりかたです。
 ただし、この方法は、コントローラーがなくなってしまいます。
 したがって、これをちょっとひねって、コントローラーをいれることもしめします。

 コントローラーを入れる場合は、コントローラーで分岐先を管理する方法と、コントローラーでは管理しない方法があります。

 詳しくは、気の向いたときに。。。また。



  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする