[解決済み] デザインパターン Webベースアプリケーション【終了しました
質問事項
簡単なWebベースのアプリケーションを設計しています。私はこのWebベースのドメインに新しいです。私は、サーブレット間でどのように責任を分配するべきか、新しいサーブレットを作るための基準など、デザインパターンに関するあなたのアドバイスが必要です。
実は、私のホームページにはいくつかのエンティティがあり、それぞれに追加、編集、削除のようなオプションがあります。以前は、Servlet1がentity1の追加、Servlet2がentity1の編集といったように、オプションごとに1つのServletを使っていましたが、この方法では、結局、多数のServletを持つことになりました。
今、私たちはデザインを変えているところです。私の質問は、サーブレットの責任をどのように正確に選択するかということです。エンティティごとに1つのサーブレットを用意して、そのエンティティが持つすべてのオプションを処理し、リクエストをサービスレイヤーに転送するようにすればいいのでしょうか。それとも、ページ全体のリクエストを処理し、対応するサービスレイヤーに転送する、ページ全体に対して1つのサーブレットを持つべきでしょうか?また、リクエストオブジェクトはサービスレイヤーに転送されるべきなのか、そうでないのか。
どのように解決するのですか?
ちょっとまともなWebアプリケーションは、様々なデザインパターンの組み合わせで構成されています。ここでは、最も重要なものだけを紹介します。
Model View Controllerパターン
使いたいコア(アーキテクチャ)なデザインパターンは Model-View-Controller パターン . その コントローラ を直接作成/使用するサーブレットで表現されます。 モデル と ビュー をリクエストに基づかせます。は、その モデル は、Javabeanクラスで表現される。これは、多くの場合、さらに ビジネスモデル アクション(振る舞い)を含む データモデル であり、データ(情報)を含む。その ビュー に直接アクセスできるJSPファイルによって表現されます。 データ ) モデル EL (Expression Language)によるものです。
そして、アクションやイベントの処理方法によるバリエーションがあります。ポピュラーなものは
-
リクエスト(アクション)ベースのMVC : これが最もシンプルな実装です。この場合、( 事業内容 ) モデル は直接
HttpServletRequest
とHttpServletResponse
オブジェクトを作成します。リクエストパラメータを収集し、変換し、検証するのは (ほとんど) あなた自身です。そのため 表示 は、プレーンなバニラ HTML/CSS/JS で表現でき、リクエスト間で状態を維持することはない。このため、特に スプリングMVC , Struts と ストライプ が動作します。 -
コンポーネントベースのMVC これは実装が難しいですね。しかし、よりシンプルなモデルとビューになり、すべてのquot;raw;Servlet APIが完全に抽象化されます。リクエストパラメータを自分で収集し、変換し、検証する必要はないはずです。そのため コントローラ はこのタスクを行い、収集、変換、検証されたリクエストパラメータを モデル . 必要なのは、モデルのプロパティと直接連携するアクションメソッドを定義することだけです。そのため 表示 は、JSPタグリブやXML要素で構成されるquot;components"で表現され、HTML/CSS/JSを生成します。また ビュー 後続のリクエストのために、セッションで管理されます。これは特にサーバーサイドの変換、検証、値変更イベントにおいて有用です。このようにして、特に JSF , ウィケット および プレイ! が動作します。
余談ですが、趣味で自作のMVCフレームワークを使うのはとてもいい勉強になりますし、個人的な目的であればおすすめです。しかし、プロフェッショナルになるのであれば、自分でフレームワークを作り直すのではなく、既存のフレームワークを選ぶことを強くお勧めします。既存のよく開発されたフレームワークを学ぶことは、自分で堅牢なフレームワークを開発・維持するよりも長期的には時間がかからないからです。
以下の詳細な説明では、実装が簡単なリクエストベースのMVCに限定して説明します。
フロントコントローラーのパターン ( メディエーターパターン )
まず
コントローラ
の部分を実装する必要があります。
Front Controllerパターン
(これは
Mediatorパターン
). これは、すべてのリクエストの集中エントリーポイントを提供する単一のサーブレットのみから構成されるべきです。それは
モデル
は、pathinfo や servletpath、メソッドや特定のパラメータなど、 リクエストによって得られる情報に基づいています。また
ビジネスモデル
というのは
Action
では
HttpServlet
の例です。
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
Action action = ActionFactory.getAction(request);
String view = action.execute(request, response);
if (view.equals(request.getPathInfo().substring(1)) {
request.getRequestDispatcher("/WEB-INF/" + view + ".jsp").forward(request, response);
}
else {
response.sendRedirect(view); // We'd like to fire redirect in case of a view change as result of the action (PRG pattern).
}
}
catch (Exception e) {
throw new ServletException("Executing action failed.", e);
}
}
アクションを実行すると、ビューの場所を特定するための識別子が返されるはずです。最も簡単なのは、それを JSP のファイル名として使用することです。このサーブレットを特定の
url-pattern
で
web.xml
は、例えば
/pages/*
,
*.do
または単に
*.html
.
プリフィックスパターンの場合、例えば
/pages/*
のような URL を呼び出すことができます。
http://example.com/pages/register
,
http://example.com/pages/login
などを提供し
/WEB-INF/register.jsp
,
/WEB-INF/login.jsp
を適切な GET および POST アクションで指定します。部品
register
,
login
で利用できるようになります。
request.getPathInfo()
上記の例のように
のようなサフィックス・パターンを使用する場合、以下のようになります。
*.do
,
*.html
のようなURLを呼び出すことができます。
http://example.com/register.do
,
http://example.com/login.do
などがあり、この回答のコード例を変更する必要があります(また、この回答の
ActionFactory
を抽出するようにします。
register
と
login
による部品
request.getServletPath()
の代わりに
戦略パターン
は
Action
の後に続く必要があります。
戦略パターン
. に基づいて作業を行う抽象/インターフェース型として定義される必要があります。
渡された
の引数は、抽象的なメソッドの引数です(ここが
コマンドパターン
で渡された引数に基づいて、抽象/インターフェース型が処理を行います。
作成
実装の)。
public interface Action {
public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception;
}
を、(1)のように
Exception
のようなカスタム例外を使用して、より具体的にします。
ActionException
. これは基本的なキックオフの例であり、あとはすべてあなた次第です。
の例です。
LoginAction
これは (その名の通り) ユーザーをログインさせるものです。この
User
は、それ自体が
データモデル
. その
ビュー
が存在することを認識します。
User
.
public class LoginAction implements Action {
public String execute(HttpServletRequest request, HttpServletResponse response) throws Exception {
String username = request.getParameter("username");
String password = request.getParameter("password");
User user = userDAO.find(username, password);
if (user != null) {
request.getSession().setAttribute("user", user); // Login user.
return "home"; // Redirect to home page.
}
else {
request.setAttribute("error", "Unknown username/password. Please retry."); // Store error message in request scope.
return "login"; // Go back to redisplay login form with error.
}
}
}
ファクトリーメソッドパターン
は
ActionFactory
の後に続く必要があります。
ファクトリーメソッドパターン
. 基本的には、抽象型/インターフェース型の具体的な実装を返す作成メソッドを提供する必要があります。この場合、このメソッドは
Action
インターフェイスを提供する。例えば
メソッド
と
パスインフォ
(pathinfoはリクエストURLのコンテキストとサーブレットパスの後の部分で、クエリ文字列を除いた部分です)。
public static Action getAction(HttpServletRequest request) {
return actions.get(request.getMethod() + request.getPathInfo());
}
は
actions
は、静的またはアプリケーション全体の
Map<String, Action>
は、すべての既知のアクションを保持します。このマップをどのように埋めるかは、あなた次第です。ハードコーディングする。
actions.put("POST/register", new RegisterAction());
actions.put("POST/login", new LoginAction());
actions.put("GET/logout", new LogoutAction());
// ...
または、クラスパスにあるプロパティ/XML設定ファイルに基づいて設定可能。(擬似)
for (Entry entry : configuration) {
actions.put(entry.getKey(), Class.forName(entry.getValue()).newInstance());
}
あるいは、クラスパスで特定のインターフェースやアノテーションを実装しているクラスをスキャンして、動的に判断します。(擬似)
for (ClassFile classFile : classpath) {
if (classFile.isInstanceOf(Action.class)) {
actions.put(classFile.getAnnotation("mapping"), classFile.newInstance());
}
}
何もしない"を作るように心がけましょう。
Action
マッピングがない場合。例えば
request.getPathInfo().substring(1)
では
その他のパターン
ここまでが重要なパターンでした。
さらに一歩踏み込むために
ファサードパターン
を作成し
Context
このクラスはリクエストとレスポンスオブジェクトをラップし、 リクエストとレスポンスオブジェクトに委譲するいくつかの便利なメソッドを提供し、 そのメソッドを引数として
Action#execute()
メソッドで代用できます。これにより、生のサーブレット API を隠すための抽象的なレイヤーが追加されます。そうすると、基本的には以下のようになります。
ゼロ
import javax.servlet.*
の宣言は、すべての
Action
の実装があります。JSFの用語で言うと、これは
FacesContext
と
ExternalContext
クラスが行っています。具体的な例は
この回答
.
次に
状態パターン
リクエストパラメーターの収集、変換、検証、モデル値の更新、アクションの実行といったタスクを分割するために、追加の抽象化レイヤーを追加したい場合です。JSFの用語で言えば、これが
LifeCycle
が行っています。
次に
コンポジットパターン
は、モデルにアタッチ可能で、その挙動がリクエストベースのライフサイクルの状態に依存するコンポーネントベースのビューを作成したい場合のためにあります。JSFの用語で言うと、これは
UIComponent
を表します。
こうすることで、コンポーネントベースのフレームワークへと少しずつ進化させることができるのです。
こちらもご覧ください。
関連
-
javaの模造品QQ WeChatのチャットルーム
-
スレッド "main" で例外発生 java.lang.ArrayIndexOutOfBoundsException: 0 at One1.main(One1.java:3)
-
スレッド "main" での例外 java.lang.ArrayIndexOutOfBoundsException: 1
-
node js npm gruntインストール、elasticsearch-head 5.Xインストール
-
SocketTimeoutExceptionの解決方法です。読み込みがタイムアウトした
-
[解決済み] Java のコア・ライブラリにおける GoF デザイン・パターンの例
-
[解決済み] Abstract FactoryとFactoryのデザインパターンの違いは何ですか?
-
[解決済み] デザインパターンについて。シングルトンはいつ使うべきですか?
-
[解決済み】関数型プログラミングはGoFデザインパターンに取って代わるか?
-
[解決済み】C++ シングルトンデザインパターン
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
java.util.NoSuchElementException 原因解析と解決方法
-
スタイルシートとして解釈されるリソースが、MIMEタイプtext/htmlで転送される。
-
eclipse で「アクセス制限: タイプ 'HttpServer' は API ではありません」というプロンプトが表示される。
-
アクセス制限です。タイプ 'Application' は API ではありません。
-
Android Studio 3.1.2 で v4, v7 パッケージが見つからない シンボル 'AppCompatActivity' を解決できない
-
Enumとの組み合わせでswitchの使い方を一度覚えるために必要な定数式
-
java Mail send email smtp is not authenticated by TLS encryption solution.
-
リソースの読み込みに失敗しました。サーバーはステータス500(内部サーバーエラー)で応答しました。
-
JSPで「リストが型解決できない!」の解決方法
-
Maven Pluginの実行がライフサイクル設定の対象外であるエラーの解決