物品管理システムのアーキテクチャをまだ決めていなかったのですが、
結局、今回は純粋なJavaのWebアプリケーションとして作成してみることにしました。
その後、WPFでWindowsアプリケーションのクライアントを作成してみたいなと計画しています。
(どんどん、ブログのタイトルにそぐわない内容になってきていてすみません。)
さて、JavaでWebアプリケーションを開発するとなると、どうしても「何のフレームワークを使うのか?」と
いう話になるのですが、今回はあえて既存のフレームワークを使わないことにします。
開発する物品管理システムは、多くても10画面ほどの小さなシステムですし、開発者も私1人です。
GAEを使って小規模のシステムを開発したいと思っている方もたくさんいると思うのですが、
私は、その小規模のシステムを開発するのに、難易度が高いJavaのフレームワークをどうしても使わないといけない
ということではないと思っています。
昨今、Javaは手間がかかって難しいというイメージが定着していますが、Javaだって極端な話、
例えばJSPだけで開発することも出来るわけです。
もちろん私はStrutsなどのフレームワークの有効性を否定しているわけではありません。
そこそこの規模のシステムにおいてはフレームワークが有効であると思います。
せっかく、Google App Engineという手軽なインフラを利用できるので、プログラムも手軽に作れればいいなと
思っているのです。
とはいえ、本当にJSPの中にビジネスロジックが混ざったり、たくさんサーブレットを作成したりという状況には
したくはありません。
そこで、今回、「HtmlControllerServlet」と「RequestHandler」というインターフェースにより構成される超シンプルな
自作フレークワークを作成しました。
「RequestHandler.java」
「HtmlControllerServlet.java」
「HtmlControllerServlet」は全てのリクエストの受け手となるサーブレットクラスです。そして、「HtmlControllerServlet」は
クライアントが指定したURLに応じて、「RequestHandler」インタフェースを実装するクラスに処理を振り分けます。

「RequestHandler」の実装クラスはパッケージ「com.appspot.myhomemgr.html.handler」に作成することをルールにしています。
URLと実装クラスのマッピングはPathInfoを利用して行います。PathInfoに直接「RequestHandler」のクラス名(パッケージ部分は省略)を記述し、
Javaのリフレクションの機構を利用して、該当クラスをインスタンス化しています。
例) URLが「http://xxxx.xx.xx/ctl/LedgerList」の場合、PathInfoは「LedgerList」になります。
(正確には/LedgerListがPathInfoになるので、substring()して先頭の/を除外しています。)
この場合、「RequestHandler」を実装する「com.appspot.myhomemgr.html.handler.LedgerList」にリクエストが振り分けられます。
後は、「RequestHandler」の実装クラスにビジネスロジックを記述し、「RequestHandler」とJSP、「RequestHandler」同士の処理の受け渡しは
普通に「RequestDispatcher」の使用して行います。
これだけでも、それぞれが密結合ですが、一応コントローラ部分は、「HtmlControllerServlet」、モデルは「RequestHandler」、ビューは「JSP」
というMVCモデルになっています。
モデルのクラス設計と生産性の向上
ここからは少し余談ですが、私はオブジェクト指向型の言語を用いてシステムを開発する場合には、
MVCのモデル部分のクラス設計をしっかりと行うことがとても重要と考えています。
多くのプロジェクトにおいて、「MVCをどのようにして実現するのか?」ということについては、良く議論され、考えられていると思いますが、
この「モデル部分をどのように作るか?」という点はあまり考えられていなかったりします。
しかし、開発の生産性という点からいうと私はここが一番大事だと思っています。なぜなら、業務ロジックの再利用とルール化はプロジェクトの生産性を
高める上では欠かせない要素であるからです。
折角、苦労してStrutsなどのフレームワークを導入しても、ビジネスロジックが開発者個人により好き勝手に作られると
結局スパゲッティソースになってしまうのです。
私が担当するプロジェクトにおいては、「モデル部分のクラス設計」を「外部設計」と並行して行います。場合によっては、この段階で
モデル部分のフレームワークを設計したりします。モデル部分のフレームワークはStrutsのような画一的なものでなく、
業務フローの分析により、明らかになる複数の業務間で共通したビジネスフローを具現化するもので、プロジェクト毎に固有のものになります。
これについてはまた、別途詳しく記事にさせていただきたいと思います。
結局、今回は純粋なJavaのWebアプリケーションとして作成してみることにしました。
その後、WPFでWindowsアプリケーションのクライアントを作成してみたいなと計画しています。
(どんどん、ブログのタイトルにそぐわない内容になってきていてすみません。)
さて、JavaでWebアプリケーションを開発するとなると、どうしても「何のフレームワークを使うのか?」と
いう話になるのですが、今回はあえて既存のフレームワークを使わないことにします。
開発する物品管理システムは、多くても10画面ほどの小さなシステムですし、開発者も私1人です。
GAEを使って小規模のシステムを開発したいと思っている方もたくさんいると思うのですが、
私は、その小規模のシステムを開発するのに、難易度が高いJavaのフレームワークをどうしても使わないといけない
ということではないと思っています。
昨今、Javaは手間がかかって難しいというイメージが定着していますが、Javaだって極端な話、
例えばJSPだけで開発することも出来るわけです。
もちろん私はStrutsなどのフレームワークの有効性を否定しているわけではありません。
そこそこの規模のシステムにおいてはフレームワークが有効であると思います。
せっかく、Google App Engineという手軽なインフラを利用できるので、プログラムも手軽に作れればいいなと
思っているのです。
とはいえ、本当にJSPの中にビジネスロジックが混ざったり、たくさんサーブレットを作成したりという状況には
したくはありません。
そこで、今回、「HtmlControllerServlet」と「RequestHandler」というインターフェースにより構成される超シンプルな
自作フレークワークを作成しました。
「RequestHandler.java」
package com.appspot.myhomemgr.base; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public interface RequestHandler { public void execute(HttpServletRequest req, HttpServletResponse resp) throws Exception; }
「HtmlControllerServlet.java」
package com.appspot.myhomemgr.base; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @SuppressWarnings("serial") public class HtmlControllerServlet extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse resp) { processReguest(req, resp); } public void doPost(HttpServletRequest req, HttpServletResponse resp) { processReguest(req, resp); } private void processReguest(HttpServletRequest req, HttpServletResponse resp) { try { String pathInfo = req.getPathInfo(); pathInfo = pathInfo.substring(1); @SuppressWarnings("unchecked") Classcls = (Class } catch(Exception ex) { try { resp.setContentType("text/html"); resp.getWriter().println("<html><head><title>エラー</title></head><body>"); resp.getWriter().println(ex.toString()); resp.getWriter().println("</body>"); } catch(Exception iex){} } } })Class.forName("com.appspot.myhomemgr.html.handler." + pathInfo); RequestHandler handler = (RequestHandler)cls.newInstance(); handler.execute(req, resp);
「HtmlControllerServlet」は全てのリクエストの受け手となるサーブレットクラスです。そして、「HtmlControllerServlet」は
クライアントが指定したURLに応じて、「RequestHandler」インタフェースを実装するクラスに処理を振り分けます。

「RequestHandler」の実装クラスはパッケージ「com.appspot.myhomemgr.html.handler」に作成することをルールにしています。
URLと実装クラスのマッピングはPathInfoを利用して行います。PathInfoに直接「RequestHandler」のクラス名(パッケージ部分は省略)を記述し、
Javaのリフレクションの機構を利用して、該当クラスをインスタンス化しています。
例) URLが「http://xxxx.xx.xx/ctl/LedgerList」の場合、PathInfoは「LedgerList」になります。
(正確には/LedgerListがPathInfoになるので、substring()して先頭の/を除外しています。)
この場合、「RequestHandler」を実装する「com.appspot.myhomemgr.html.handler.LedgerList」にリクエストが振り分けられます。
後は、「RequestHandler」の実装クラスにビジネスロジックを記述し、「RequestHandler」とJSP、「RequestHandler」同士の処理の受け渡しは
普通に「RequestDispatcher」の使用して行います。
これだけでも、それぞれが密結合ですが、一応コントローラ部分は、「HtmlControllerServlet」、モデルは「RequestHandler」、ビューは「JSP」
というMVCモデルになっています。
モデルのクラス設計と生産性の向上
ここからは少し余談ですが、私はオブジェクト指向型の言語を用いてシステムを開発する場合には、
MVCのモデル部分のクラス設計をしっかりと行うことがとても重要と考えています。
多くのプロジェクトにおいて、「MVCをどのようにして実現するのか?」ということについては、良く議論され、考えられていると思いますが、
この「モデル部分をどのように作るか?」という点はあまり考えられていなかったりします。
しかし、開発の生産性という点からいうと私はここが一番大事だと思っています。なぜなら、業務ロジックの再利用とルール化はプロジェクトの生産性を
高める上では欠かせない要素であるからです。
折角、苦労してStrutsなどのフレームワークを導入しても、ビジネスロジックが開発者個人により好き勝手に作られると
結局スパゲッティソースになってしまうのです。
私が担当するプロジェクトにおいては、「モデル部分のクラス設計」を「外部設計」と並行して行います。場合によっては、この段階で
モデル部分のフレームワークを設計したりします。モデル部分のフレームワークはStrutsのような画一的なものでなく、
業務フローの分析により、明らかになる複数の業務間で共通したビジネスフローを具現化するもので、プロジェクト毎に固有のものになります。
これについてはまた、別途詳しく記事にさせていただきたいと思います。
コメント
コメントの投稿
トラックバック
http://csfun.blog49.fc2.com/tb.php/55-b15181f4