Struts1.3でWebアプリケーションを開発してみた

## はじめに
Struts1.3を使ってWebアプリケーションを開発したので、開発を通じた経験・感想を記事にしてみました。
「今さらStruts??」というのが正直なところですが、現在入っている現場で使用されているフレームワークがStruts1.3であり、勉強も兼ねて、このフレームワークでの開発を選択しました。

以下が、ソースリポジトリ(GitHub)へのリンクです。
[struts-school-search](https://github.com/shu0n/struts-school-search)
Docker上で起動する想定の構成にしていますので、各々の環境で起動していただき、ご意見をいただければ幸いです。

## どんなWebアプリケーションを開発しよう、、、
開発するにあたって、どんなWebアプリケーションを開発するかをまず考える必要があります。
あまり簡単なアプリケーションだとあまり勉強にはなりませんし、大きすぎると完遂できずに終わってしまいます。
その辺りを考慮して、以下の目的をもったWebアプリケーションを開発することにしました。

- 主催しているスクール情報を登録して生徒の募集ができること。
- 興味のあるスクールを検索して受講の申込ができること。

上記のようなWebアプリケーションであれば、アカウント機能、投稿機能、申込機能、メッセージ機能、管理機能などの機能や対応する画面の実装が一定規模必要になりつつ、個人レベルでも完遂できる規模かなと考えました。

## 情報がない、、、
いざ開発を始めて、ライブラリを入れたり、設定ファイルを編集したり、ソースを書いたり、とするのですが、色々と分からないことが発生しました。
インターネットに公開されているドキュメントや掲示板の投稿から情報を探すのですが、昨今のフレームワークのように必要な情報がなかなか見つからず苦労しました。
それでも、トライ＆エラーを繰り返すうちに動作原理も分かるようになり、何とか開発を進めることができました。

## フレームワークとは言うけれど、、、
フレームワークとは言うけれど、まさにフレーム、外枠(ブラウザとサーバ間の入出力)のみ用意してくれているような印象でした。
モデルやDBインターフェースといった部分はほぼ自作で、昨今のフレームワークではその辺りの機能の多くが用意されているのとは対照的でした。(特にDBインターフェースの自作にはかなりの時間を要しました、、、)
また、MVCモデルを念頭に開発をしていたものの、ほぼ外枠しかないような感じなので、ディレクトリ(パッケージ)構成も試行錯誤となり、当初の構成と最新の構成ではかなり違うものとなりました。この点も、昨今のフレームワークがあらかじめディレクトリ構成を用意してくれているのとは対照的でしたが、MVCモデルを１から作るという経験ができたことは、今回の大きな収穫だなと思っています。

## ORマッパーって大事かも
ORマッパーの要/不要については議論がありますが、それなりのWebアプリケーションを開発するなら必要なんじゃないかなというのが、今回の感想です。
開発当初は各モデルに合わせてsql文を個別に書いていたのですが、進めていくうちに限界を感じました。例えば、「同じデータを持ってくるために同じsql文を複数書かなきゃいけない」とか「同じテーブルに対するinsert処理で任意のデータをsqlで簡単に入れこめてしまう」などの懸案が発生してきました。
DBインダーフェースはDAOに集約して、データの入れ出しはアクションフォームを通じて処理した方が、「どのデータ(データ型)ならinsertできる」「selectしたらこのデータが返ってくる」といったことが管理しやすくなり、モデルの追加も容易になりました。
処理速度から考えるとsqlを直接書いた方がいいかもしれないし、個人開発レベルならそこまで大きな問題にはならないと思いますが、複数人の開発者が共同で作業するようなケースになると、sqlが至るところで実装されてしまい、どのようなデータの入出力が処理に織り込まれているのか把握しずらくなったり、たった一文で必要なデータが削除されたりといった問題にも繋がりかねないんじゃないかと思います。(開発者間の技術差がそれなりだと、リスクも大きくなりそう、、、)

## カスタムタグの利用にこだわる必要はないかも
Strutsにはjspで使えるカスタムタグが用意されていますが、無理に使わなくていいと思います。むしろフロントとバックの開発を明確に分担しているようなケースでは使わない方がいいかもしれません。
カスタムタグは便利ではあるのですが、なまじhtmlの要素と名称が似通っている分、フロント担当者がHTMLやCSS(＋ JavaScript)しか分からないよう場合は、誤解させてしまう危険があります。無理にカスタムタグは使わずにディレクティブに置き換えた方が、動的な箇所が明確になり、フロント担当者も開発を進めやすくなるように思います。(逆に画面のHTML一式が先に存在する場合も、バック担当者が動的箇所を埋め込みやすい)

## MVCってこんな感じ
MVCと言葉では聞くし言うけど、今回の開発でその本質の一端を理解できたように思います。
Strutsの場合は以下のような役割分担だと思っています。

- Model：自作(今回はmodel(+ util)パッケージに実装・配置)
        - Ruby on RailsなどのModelはDBインターフェースに近く、本システムではDAOが担う処理
- View：jsp
- Controller：Action(今回はactionパッケージに実装・配置) + struts-config.xml

具体的な処理(俗にいう業務ロジック)を全てmodelに実装することで、Actionは処理仕様書(どのmodelを呼び出すか)のようなものになりました。
また、modelからの処理結果をActionFormに格納することで、jspはその中身を投影するだけでよくなりました。(Actionはタッチしなくて済む)
上記のような実装を見ると、MVCが「受け付けたリクエストをもとにControllerがModelを操作して、Modelの処理結果(ActionForm)をViewが投影する」ものということが実感できました。

## 単体試験は大切
単体試験はJUnitを使用し、ソースのJavaファイルに一対一対応するようにテストのJavaファイルを書きました。
本来はソースを書く前にテストを書くべきですが、JUnitが初めてでなかなか手が出ず、一通りソースを書いてからテストを書いてしまいました、、、
それでも、テストを書くことで、思いもよらぬバグ(引数が間違っているなど)を発見できたり、不要な処理を整理できたりと、ソースの品質を高める上では必須のステップだと改めて実感しました。
また、テストを書いておくことで、修正時確認に要する時間が大分節約できました。この点、今の現場が手作業での単体試験をメインとしているので、その差の大きさが如実に感じられました。(書いたテストの内容も同時に大切ではありますが、、、)
今後は「テストを書く→ソースを書く→テスト実行→ソース修正」(いわゆるテスト駆動型開発)ができるようになるのが課題と考えています。

## コメントはそこまで書かなくても良いかな、、、
今回の開発では、ソースコードの各行にコメントを書くようにしました。これは、今回公開したリポジトリが初学者の参考になればという思いがあったからです。
しかし、実際の開発ではそこまでコメントを書く必要はないと思っています。特に処理の記述順番や変数名・メソッド名を工夫すれば、コードを見るだけで処理の内容は概ね把握できるかなと思います。(昨今のマシンスペックなら変数名・メソッド名が長くなっても処理速度に影響は出ませんし、IDEを使用していれば補完もしてくれます)
また、テストコードには基本的にコメントを記載していません。これはテストコードは仕様書も兼ねるものだと考えているからです。コードを読むだけでは処理が分からないということは、テストコード自体が複雑化していることでもあるので、コード自体を見直すべきかもしれません。

## 最後に
Strutsを使った開発について、いろいろと経験・感想を書いてみました。今後の新規開発で使用されることはないでしょうが、既存のWebアプリケーションでは未だに現役なフレームワークですので、少しでも開発者の方のご参考になれば幸いです。