siteあるプログラマの勉強部屋。プログラムcivic以前の記事(Struts開発での考察)から継続してStrutsの開発パターンを1つ作成してみました。作成するものが少ないパターンだと思います。前提として、データベースの構造なんですが、商品データベースの一覧画面を想定しています。画面のイメージはこんな感じを想定しています。一覧画面のイメージ、編集画面のイメージ特に難しいことはないと思います。このテーブルに対する一覧画面と、編集画面を作成することを考えて、ロバストネス図を書きました。初めに動作するのは、検索アクションです。DBからProductsテーブルを全件検索し、一覧画面に検索結果を渡します。一覧画面の「編集」リンクをクリックすると、その商品の編集画面を表示します。これが編集アクションです。編集アクションは、編集画面を表示するだけの処理で、更新処理は行いません。編集画面から「更新」ボタンを押すと、更新アクションが動作します。更新アクションはデータベースの更新処理を行い、更新アクション自体は画面を表示せず、検索アクションに連鎖します。<<submit>>は、ブラウザからのサーバへのHTTPリクエストの流れになります。<<forward>>は、ActionからJSPへのフォワードになります。<<action-chain>>は、ActionからActionへのフォワードのことですが、Action-Action間の連鎖を区別してaction-chainと呼んでいます。ここでは、更新処理が終わった後に、検索処理に連結して、再び一覧画面を表示するために使っています。更新アクション中に、検索のための処理を記述する必要はなくなります。ソースこのソースファイルはkenkyu01.zipになります。Struts関係のライブラリは、サイズが大きくなるので削除してあります。(WEB-INF/lib配下)DB周りの操作にDBUtilsを使っています。Strutsのカスタムタグはstruts-htmlのみ使用し、あとはJSTLを使用しています。注目すべきところ編集アクションでは、2つのActionFormを使っています。1つは、一覧画面から送信されたものです。Strutsにより生成されたProductEditFormをキャストして使用します。1つは、編集アクションでnewして生成したものです。編集画面には、formタグが配置されています。このアクションで使用するActionFormがProductUpdateFormであるため、これをnewしてsetAttributeしています。編集アクションはDBからデータを取得して返却するわけですが、その返却の方法としてActionFormを使用しています。返却のためにActionFormを使用するのは、返却後にテキストボックスなどのform部品として使用する場合のみです。それ以外のケースでは、リクエストスコープの変数を使って画面にデータを転送します。一覧画面では検索結果のListをリクエストスコープのデータとして返却しています。Strutsの設計パターンというよりも,Webアプリの設計パターンになるのですが、データベースへの接続処理は、ServletFilterで行っています。ServletFilterのinit処理で、DataSourceを取得し、あとは1つのHTTPリクエストごとに、DB接続を生成し、リクエストの終了時に切断しています。ActionServletを継承し、executeメソッドを呼び出す前にDB接続する方法もありますが、アクション連鎖の際に再び接続してしまうので、HTTPリクエストの単位でDB接続を継続するようにしました。トランザクションは、例外が発生しなければ常にコミットし、例外発生時にロールバックするようにしました。このため、各アプリケーションではコミットやロールバックする必要はなく、例外を投げるか正常に終了するかで決定します。正常処理でロールバックするというケースは少ないので、このような実装にしました。Object)を使用していません。MapやListなどの汎用的なコレクションクラスで代用しています。することで、新たなクラスを作成する必要がなくなりますが、反面静的な型チェックが行われなくなります。JSPで、${product.pname}と記述できるのは、Mapに対して”pname”という文字列をキーに、商品名を格納してあるからです。JSP-ELで非常に簡単に記述できています。Object)は用意していません。SQLがシンプルな場合などは、DAOを作成しなくてもActionクラスで処理してしまっていいのではないか?と思うのが私の考え方です。DAOを作成する場合には、画面とは切り離して、Entityとしての役割を果たす形で考えるべきだと思います。私の会社で開発している人を見ていると、DAOを作成するのはいいんですが、画面ごとにDAOを作成しているのを見かけます。そのため、同じようなSQLがあちこちのDAOに存在し、単にActionのソースファイルから、抜き出してDAOを作っているだけになっています。なるくらいならば、Actionに記述したほうが、ロジックが分散しなくて見やすいです。DAO単独で再利用したりなんてしたことないし。(それどころか、DAOにActionFormを引き渡したりしているのを見かけたりもします←再利用できなくなる)DAOの作成単位は、オブジェクト指向のモデリングによって決定すると思います。「画面1つにつきDAO1つ」とルール化したい気も分からないでもないですが、ルール化したければ、「テーブル1つにつきDAO1つ」の方が良いと思います。ビジネスロジックの実装箇所についてActionクラスから利用されるビジネスロジック用のクラスも作成していません。Actionに記述します。ビジネスロジックは、別途作成した方がよいかも知れません。本当にそのビジネスロジックを再利用できるように作成するつもりでビジネスロジックを別に分けるべきだと思います。分けたはいいが、結局、再利用できなくて別ファイルにロジックがジャンプしているだけにならないようにすべきです。まとめると、今回の開発パターンはこのような感じです。開発パターン1DTO使用せずに汎用的なコレクションを使用Actionクラスを継承して作成DAOを作成せずに、Actionクラスでビジネスロジックを作成1Action-1ActionFormのルールで作成(ActionFormのないActionも可)これをベースとして、他のパターンも応用して作成してみたいと思います。PMDOONといいます。参考にしたくて読んでます。できるだけソースを書きたくないので参考になります。いままでVBで組んでたのですが、急にJavaをやれと・・・・。私が今回やる画面では、html:linkに当たるところをみため的にボタンにして欲しいといわれています。(編集ボタン、新規作成ボタン)となります。type=”submit”とTable内のデータが、ひもづかないです。真似をしながら作成していたのですが、そこで躓いています。typeにはなくて困っています。Action-Chainはぜひ、実践したいのですが・・・。Type=”submit”を関連付けるのが難しいです。何行目のボタンがクリックされたかとかも、paramNameがないと判定しにくいです。その場合、どのようにやられますか?迷惑でなければ考え方を教えてください。type=”hidden”で、選択された行を識別するコードを保持するようにします。(表示した時は空です)submitボタンを押した時にonclickのJavaScriptでhiddenに選択行の情報をセット。→これを使う場合にはonclick属性のJavaScriptコードを動的にセットする必要があります。返事ありがとうございます。JavaScriptですか。Strutsではないということは、板違いの質問ですね。なんかhtml:linkを継承したbutton見たいなものが作れるのかなーとか考えていました。教えていただいたのをやってみようかと思います。これは、ボタンクリックのアクション時に、selectedPcodeをActionの中で取れるということなんですよね。それすら、まだ理解できていません。明日までには報告できると思います。PMすぐですいません。ここで教えてもらったEasyDispatchActionを元に作成しています。_edit_とかしています。なんか、初歩的な質問で申し訳ないですね。一つを優先すると、一つがおかしくなっての繰り返しで・・・。Type=”submit”でやっていまして、ボタンにも色をつけたいのでid=MYCOLORとかもやってまして・・。それも、引っかかりそうです。webはlinkでやるのが、基本なんでしょうかね?もう一度、客先にレイアウト変更をだしてみようかなーと思っています。PMいやいや、linkでなくてもできますよ。type=”submit”でやらないといけません。整理して落ち着いて考えてみてください。