📘 Vol.11.2.1 アクション層の役割と設計パターン ―「ただのリクエスト受け口」から「ユースケースの橋渡し役」へ―

### 🟦 導入：Struts2アプリが“分かりにくくなる”原因はアクション層かもしれない
Struts2で開発されたWebアプリで、こんなことを感じたことはないでしょうか？

- Actionクラスの行数がどんどん増えていく

- 似たような処理をするメソッドがActionに散在している

- 画面の戻り先や遷移先のロジックがわかりにくく、メンテナンスが大変

- 入力チェックや状態遷移のルールがActionに埋もれてしまっている

Struts2は柔軟な設計が可能なフレームワークですが、**「Action層が担う役割と設計の方針」があいまいなまま実装を進めると、徐々に肥大化・複雑化していく**という落とし穴があります。

そこで本記事では、**Struts2におけるアクション層の「本来の役割」** を整理しつつ、よく使われる設計パターンとその適用シーンを紹介します。

---

### ✅ 1. はじめに：Actionは“ただのリクエスト受信機”ではない
Struts2のActionクラスは、リクエストごとにインスタンスが生成され、`execute()`（もしくは指定されたメソッド）が呼び出されます。これはフレームワークとしては非常に分かりやすい構造です。

しかし、多くのプロジェクトで以下のような設計が見られます。
```java
public class UserAction extends ActionSupport {
    private String name;
    private int age;

    public String execute() {
        if (name == null || name.isEmpty()) {
            addActionError("名前を入力してください");
            return "input";
        }

        // DAOを直接呼び出して登録処理
        new UserDao().insert(name, age);
        return "success";
    }
}
```

このような実装では、**入力チェック・業務ロジック・遷移制御**がすべて1つのexecute()に詰め込まれており、以下の問題が発生しやすくなります。
- 単体テストしにくい

- 処理の責任範囲があいまい

- 別の画面やユースケースで再利用しづらい

Actionを「単なるリクエスト受信口」と捉えるのではなく、**「ユーザー操作をアプリケーションのユースケースに翻訳し、正しい処理の流れを制御するレイヤー」** と再定義することで、見通しの良い設計が可能になります。

---

### ✅ 2. Action層の理想的な役割とは？

Struts2のAction層は、MVCの「C（Controller）」に該当します。ただし、Spring MVCなどと違って、Struts2のActionはインターフェースや継承を使って多くの責任を負うため、よりアプリケーションロジックに近い位置にあります。

### 💡 Actionの本来の役割とは？

以下の5つが、Struts2におけるActionの“理想的な”役割です。

| 項目                | 説明                                 |
| ----------------- | ---------------------------------- |
| ① UIイベントの受信       | 画面のボタン操作やフォーム送信など、ユーザーの意図を受け取る     |
| ② パラメータの自動バインディング | フォームの入力値をプロパティにマッピングする（OGNL）       |
| ③ 入力バリデーションの制御    | `validate()`やXML/アノテーションによるバリデーション |
| ④ Service層の呼び出し   | 業務処理やDB操作はServiceに委譲する             |
| ⑤ 遷移の判断と制御        | 業務処理の結果に応じて、次に表示すべき画面を選択する         |


---

✅ 他のレイヤーとの関係
- DAO層との直接接続は避ける（Service層を通す）

- ビジネスロジックはService層に任せる

- Actionは「画面単位」「ユースケース単位」で設計するのが理想

```plaintext
[View (JSP)]
   ↓ submit
[Action] ---(呼び出し)---> [Service] ---(データ操作)---> [DAO]
   ↑ 遷移判断
   ↑ バリデーション
```

> **✍️ Point：**
「画面の操作」と「業務処理」を明確に切り分ける。Actionはその“橋渡し役”です。

次回は、以下の3つのアクション設計スタイルを具体例付きで紹介していきます：

- 1クラス＝1ユースケース型

- 1クラス多メソッド型

- 共通BaseAction抽出型（責務分離）

次記事はこちら → 📘Vol.11.2.2 に続く予定です！


---
### ✨ シリーズまとめ（Vol.11.2.xx アクション層設計）

- [✅ Vol.11.2 UX改善に効く！アクション層設計と入力制御の極意（プロローグ） ― アクション層からはじめるStruts2の“わかりやすい画面遷移”と“操作性向上” ―](https://qiita.com/drafts/c69962826bb29639c351/edit)

- [✅ Vol.11.2.2 アクションクラスの3設計スタイルと選定基準 ― 機能粒度・責務分離・保守性のバランスをどう取るか？ ― ](https://qiita.com/juehara-crypto/items/88b7634a64b1ad564668)

- [✅ Vol.11.2.3「戻り先制御と画面遷移の設計パターン」](https://qiita.com/juehara-crypto/items/c5165c92a4366fd1962b)

- [✅ Vol.11.2.4「セッションとパラメータの使い分けと設計ポイント」](https://qiita.com/juehara-crypto/items/06162659215cca86de28)

- [✅ Vol.11.2.5【トラブル防止】アクション層の共通処理とメンテナブルなBaseAction設計 ](https://qiita.com/juehara-crypto/items/b538b50eaa9c263a31bb)



---

### 🧭 関連記事（Vol.11.xxxシリーズ）
| 連番           | タイトル                                                  | 内容分類              |
| ------------ | ----------------------------------------------------- | ----------------- |
| [Vol.11.0](https://qiita.com/juehara-crypto/items/a0cc66893cb499a6e23a)     | Struts2が提供してくれる便利機能まとめ9選                              | 導入＆概要             |
| [Vol.11.1](https://qiita.com/juehara-crypto/items/0a584da537059dd43a7c)     | 自動注入とステートレスActionの仕組み                                 | フレームワーク内部理解       |
| [Vol.11.2](https://qiita.com/juehara-crypto/items/c69962826bb29639c351) | **UX改善に効く！アクション層設計と入力制御の極意（プロローグ）**                   | UX設計・アクション層総論     |
| [Vol.11.2.2](https://qiita.com/juehara-crypto/items/88b7634a64b1ad564668)   | 【UX重視】戻るボタン・キャンセル処理の設計手法と「戻り先管理」のスマート実装               | 戻り先制御とUX設計        |
| [Vol.11.2.3](https://qiita.com/juehara-crypto/items/c5165c92a4366fd1962b)   | 【設計ノウハウ】多画面遷移時のパラメータ受け渡し・保持戦略（セッション vs hidden vs URL） | パラメータ多重管理         |
| [Vol.11.2.4](https://qiita.com/juehara-crypto/items/06162659215cca86de28)   | 【実践ガイド】ユーザー操作を考慮したアクション遷移設計（リダイレクト vs フォワードの使い分け）     | UX遷移設計／Result制御   |
| [Vol.11.2.5](https://qiita.com/juehara-crypto/items/b538b50eaa9c263a31bb)   | 【トラブル防止】アクション層の共通処理とメンテナブルなBaseAction設計               | アクション共通化／保守性      |
| [Vol.11.3](https://qiita.com/juehara-crypto/items/913de7c942a9242201e8)     | Struts2の defaultStack とは？Interceptorの中身を詳しく追ってみる      | Interceptor       |
| [Vol.11.3.2](https://qiita.com/juehara-crypto/items/ede8d3c2a9b147f6161e)     | 🔧 Vol.11.3.2 独自Interceptorの作り方と使い所 _Struts2のカスタマイズを“実践で使えるレベル”に一歩進めよう_     | Interceptor       |
| [Vol.11.4](https://qiita.com/juehara-crypto/items/253142d13fe5f604610f)     | 入門者のための「パラメータ自動バインディング」完全理解ガイド                        | 自動バインディング         |
| [Vol.Vol.11.4.1](https://qiita.com/juehara-crypto/items/4fd8ed2a8be317f6e1bd)     | 入門者のための自動バインディング実践パターン集                        | 自動バインディング         |
| [Vol.11.5](https://qiita.com/juehara-crypto/items/6ef7a87a54163d81a9ba)     | Struts2の構成理解が“実務レベル”へと進化する決定版         | 設定ファイル構造          |
| [Vol.11.5.1](https://qiita.com/juehara-crypto/items/df407b24101e92a02eab)     | Struts2の“画面遷移の全体像”を理解するためのマイルストーン記事         | 設定ファイル構造          |
| [Vol.11.6](https://qiita.com/juehara-crypto/items/bfbdc2203acac7ba3f19)     | ActionSupport の便利メソッドと国際化対応                           | ユーティリティ / i18n    |
| [Vol.11.7](https://qiita.com/juehara-crypto/items/ed8f0977c23ee8c8b959)     | validate() / input 戦略とUX設計                            | 開発スタイルの違い    
| [Vol.11.8](https://qiita.com/juehara-crypto/items/bb2b23612c22fa9bf50b)     | アノテーションベースの設定 vs XML定義の比較                             | 開発スタイルの違い         |
| [Vol.11.9](https://qiita.com/juehara-crypto/items/6163ad6c9308cc8dda6d)     | バリデーション完全解説（XML / アノテーション）                            | バリデーション（※Vol.8補完） |
| [Vol.11.10](https://qiita.com/juehara-crypto/items/207cb3d7f0a889c54df9)     | Struts2の「OGNL」ってなに？しくみと使い方をやさしく解説                     | 式言語OGNL解説         |
| [Vol.11.11](https://qiita.com/juehara-crypto/items/c313ea56f97984756c05)    | ModelDriven インターフェースの使いどころと注意点                        | Model駆動開発         |
| [Vol.11.12](https://qiita.com/juehara-crypto/items/de7a17d53e53d6466f17)    | SessionAware と RequestAware でセッション/リクエスト管理            | セッション管理           |
| [Vol.11.13](https://qiita.com/juehara-crypto/items/539bd5bae75a8e154753)    | Resultタイプ完全解説（dispatcher / redirect / stream など）      | 遷移パターン理解          |
| [Vol.11.14](https://qiita.com/juehara-crypto/items/142d9aa2c623c5eb70bc)    | Vol.11.14 ValueStackの中身を理解する – 画面とActionの橋渡し役                 | Action            |
| [Vol.11.15](https://qiita.com/juehara-crypto/items/84f024816d0cf2212cb6)    | Interceptorチェーンを自作してみよう（ログ / 認証フィルタ）                 | Interceptor            |
| [Vol.11.16](https://qiita.com/juehara-crypto/items/ff3ad75f9ee45fcd0f8f)    | エラー処理と例外ハンドリングの実践パターン                                 | ハンドリング設計          |
| [Vol.11.17](https://qiita.com/juehara-crypto/items/0d8d5101ff39b34b4704)    | Struts2でファイルアップロード機能を実装する方法                           | 実装系Tips           |
| [Vol.11.18](https://qiita.com/juehara-crypto/items/d93c8d9cee719997c068)    | 非同期通信（AJAX）とStruts2の連携方法                              | フロント連携編           |
| [Vol.11.19](https://qiita.com/juehara-crypto/items/dd6cf06d3100c9204d1f)    | セキュリティ対策（CSRF, XSS, パラメータ偽装）                              | セキュリティ対策           |
| [Vol.11.20](https://qiita.com/juehara-crypto/items/9442d9f4705f1c6c4da1)    | 複数フォームを安全に扱う！セッション管理と動的フォームの考え方                              | セッション管理           |
| [Vol.11.21](https://qiita.com/juehara-crypto/items/78eb217727b7c97f228a)    | Struts2でJSONを返す！REST API連携と非同期通信の基本設計                              | セッション管理           |
| [Vol.11.22](https://qiita.com/juehara-crypto/items/424155ee0e567a36b9a1)    | 本番環境構成とセキュリティ設計（Apache+Tomcat+Struts2連携）                             | 外部公開           |

---