Teedaでの開発ポリシー

私が思っている小規模から中規模向けのTeeda開発ポリシーです。
大規模はそもそもSAStrutsを(あわわ)

前提の前提

オフィシャルサイトの『現場で役立つ実践Teeda』(http://teeda.seasar.org/ja/presentations.html)が標準的な開発環境をきれいに記述しているドキュメントになります。

全体的にここのプレゼンテーション資料は非常に質が高いので、すべて目を通しましょう!

前提

データベース周りの処理はDBAが担当、ロジックはロジック専用の人が担当、画面は画面専用の人が担当っていう階層わけした開発用ではありません。機能ごとでの分担を前提としています。

また、デザインパターンを意識しないでいます。そもそもデザインパターンは作っていて問題がでたから導入する流れが好ましいと思っているので、無駄に複雑なデザインパターンありきで実装をするのもどうかと思っています。なので、Strutsなどで昔からJavaで開発していた人には違和感があると思いますし、規模の大きな開発には向かないと思います。

設定をすれば変えられる物も極力デフォルト設定で使うようにしています。

レイヤーとコンポーネントの取捨

最小の状態から検討していきます。

ページクラスって必要ですか?

必要です。無いと表示できないですもんね。

アクションクラスって必要ですか?

んー、微妙ですが、無くても大丈夫かな?
画面ごとに作ったり、作らなかったりをするのであればすべて作らない方がすっきりすると思います。個人的には作ったことありません。すべてのページで大量の入力項目がある場合などはすっきりするので別けたほうがいいと思います。あとはsetter、getterがある場合。。。

サービスって必要ですか?

これは必要だと思います。デフォルトではService以下の処理はトランザクションがかかります。トランザクションを利用しない場合にはページクラスのみで処理できますが、複数のページから呼ばれる処理はサービスに定義した方がいいと思います。

ロジックって必要ですか?

よほど大掛かりなシステムでなければ必要ないと思っています。基準としてはサービスの中身がほぼ空っぽで、すべてロジックで処理を行っている場合などは別れている必要がないと思います。個人的にはサービス+ロジックをサービスでまかなっています。

Daoって必要ですか?

データベースを利用する上では必要ですね。

Entityって必要ですか?

データベースを利用する上では必要ですね。

Dtoって必要ですか?

forEachの処理があるので必要になってくると思います。

Dxoって必要ですか?

んー、個人的にはあまり使いたくない機能です。便利ですがEntityに少し項目が増えた程度であればそのままDaoにつっこんだり、データをループして変更点のみ更新するような処理を作ったりします。

Dxoで変換後に、自動変換できない部分があって手で詰め替えを行うのであれば、最初から専用の更新用メソッドでフィールドごとに処理がわかるようにした方がいいと思います。

開発思想など

モックって必要ですか?

個人的には嫌いな機能です。たしかに便利ですが、単体テスト終わっているけど結合テストしたらぼろぼろだっていうプロジェクトの原因の一つがモックだと思います。

たとえば新規登録時にログインIDが既存で使われていないかなどのチェックの場合、モックを作るより実際にDBに問い合わせた方が早いと思います。

個々は動いているように見えても、都合のよいデータをモックに与えて動いている場合も多いので、注意しましょう。。。

Teedaはページ駆動のフレームワークですので、外部システムとの連携など相手がある物以外は基本的には実際に動かして開発を進めるスタイルがいいと思います。

インターフェースって必要ですか?

設計上絶対に必要であれば使ってもいいと思います。デザインパターン的に必要だからって作るのであれば無駄なコードだと思います。

インターフェースと実態が1対1でしか存在しないケースの場合、ページクラスから特定のDaoのメソッドを呼び出すまでに、サービスのインターフェース、サービスの実態、ロジックのインターフェース、ロジックの実態、Daoのメソッドとソースを追加していくのはどうも好きになれません。

ただし、テストなどでのメリットもあるはずですので、階層が浅い場合には利用してもよいと思います。上記の場合には処理によりますが個人的にはページクラスからDaoを直接操作した方が直感的だと思います。(インターフェース関係ない。。。)

テストケースって必要ですか?

もちろん、無いよりあった方がいいです。ただしここに無駄に時間をかけているのはどうかなと思います。テストをするのであれば本当に必要なことをテストしましょう。

都合のいいデータばかりを使っているテストケースで、データのカバレッジも足りなくてまったく意味無いけれど、作業時間はかかっているものを見たことがあります。

テストケースは100%動くけれど、実際に触るとぼろぼろだったりするんですよね。。。一般的にJava系のエンジニアは実際に画面をさわるテスト工数が足りない気がします。前後の機能の流れまでの確認が抜けていて、自分の担当が動いていればOKって感覚がどうも好きになれません。

モンキーテストと呼ばれるフリーのテストをまったくしない場合もあったりして、テストケースを作るのはいいけれど、ケース漏れにはどう対応するのって思ったりします。

Webコンテンツ系の開発の場合には使い勝手や反応時間まで含めて、早めに実際に動かしていくのが重要だと思います。そもそも仕様と違うけれど、ものすごく作りこんだテストケースって負の遺産ですよね。。。

Seleniumのような外部からのテストも非常に有効だと思います。

ページクラスに処理を書いちゃだめ?

複数のページクラスで使う処理はサービスにまとめて、それ以外はページクラスで処理するようにしています。Windows系アプリの開発をやっていたかもしれませんが、その方が見通しがいいんですよね。

トランザクションが必要なものや、エディタ上で1ページに収まらないような複雑な処理はサービスに分離しています。

Javadocは書かないとだめ?

エンジニアのためのJavadoc再入門講座(ISBN:9784798119489)をお勧めします。

ただし、この本もどちらかというとモジュール単位での大規模開発向けドキュメントなので、Javadocに使っちゃだめと書いておけばエラーが起きても自分の責任じゃないよっていうスタンスなので、その辺はいいところだけ取り入れましょう!

とくにJavadocに関係ないソース部分のコメントは必要ないと書いてありますが、保守をしていく上では重要な場合もありますのでなるべく入れたほうがいいと思います。逆にメソッド名を単に日本語化したコメントは必要ないとあり、書くのであればどんな値を許容するのかなども書きましょう!

公開しない関数なども保守をしていく上では、必要なことも多いので書いた方がいいですね。ただし必要以上に書く必要はないと思います。過去にすべてのsetterとgetterにプロパティー名の日本語訳がそのまま入っているだけのJavadocコメントを見たことがありますが、あれは無駄ですね。。。

無駄なコメントを書くのであれば、必要なコメントを充実させましょう!

プロパティはpublicじゃだめ?

画面上にものすごくたくさんの入力項目などがあるとソースのほとんどがsetterとgetterになったりしますよね。setterとgetterでなにか必要な処理をしているのであれば仕方ないですが、単に自動生成できるものを書いているのであればpublicですっきりした方がいいと思います。

Checkstyleって必要?

使ってもいいと思いますが、使うのであればちゃんと使っているJavaのバージョンにあったものを利用してください。Java5を利用しているのに古い物を使っていて、総称型とかの警告は無視するとかはやめてください。

社内規約って必要?

すべてに絡んできますが、社内規約は最低限のものにするか、ちゃんと更新していきましょう!
とはいえ、社内規約ってものすごく規定するの面倒ですよね。そして変更も面倒なので古いまま残ってしまう。コードスタイルとかは社内規約じゃなくってEclipseの標準の書き方でもいいと思うんですよね。

単体テストってどこまで?

たとえば新規ユーザー登録の場合、画面から実際に登録してDBにデータが書き込まれて、あればメールが届くまでが私は単体だと思っています。

たぶん、一般的なJavaでいう単体テストじゃなくって結合テストになるのかな? ただTeedaであればメールはちょっと面倒だけれど、それ以外はすぐに組めるのでそこまで作った方がトータルでは早いと思うんですよね。

DBのスキーマー管理って必要?

絶対に必要だと思います。
ソリューションとしてはS2JDBC-Genを私はお勧めします。理由としては、Teedaは通常S2Daoを利用しているので、スキーマー管理のプロジェクトを別けることになるからです。

もちろんDBFluteを内部で利用しているのであれば、DBFluteがベストだと思います。ただしS2Daoの機能しか使っていなくってDBFluteスキーマー管理になるとプロジェクト内に開発では利用しないファイルが増えることになりますので、ちょっと開発者が混乱しますよね。

なので、思い切って別プロジェクトに別けてEntityとかも二重管理にします。こうすることで本体のプロジェクトは余計なファイルが入らなくてすっきりします。S2JDBC-Genの使い方は去年の日記がありますが、ちょっと内容が古いので今度書き直したいと思います。

DBにはコメントを入れましょう!

絶対必要!
開発に利用しているツールによると思いますがA5:SQLhttp://www.wind.sannet.ne.jp/m_matsu/developer/a5m2/)などコメントがわかるSQLエディタを利用している場合には非常に便利です。CSEhttp://www.hi-ho.ne.jp/tsumiki/)も便利なのですが、コメントが見えないんですよね。

あとはDB定義書はDBのスキーマー情報から自動生成とかしているので、コメント入れないと日本語名でないんですよね(笑)

ER図って必要?

ケースバイケースですよね。私は見ません。DB定義書をみて頭の中でSELECTとかの検索がうまく連結するのかを考えます。私は脳みそ上のオンメモリで考えるので、100人月以上とかのでかいプロジェクトは苦手なんですよね(苦笑)

とはいえ、視覚化して頭に入れる人もいると思いますので、メンバーが必要であれば作りましょう。

プロトタイププロジェクトって必要?

私は要件定義の間から、プロトタイプ作ってデータ構造とかの検証をします。必要なデータ量より多目のデータを入れて、検索などのレスポンスが大丈夫かを検証したり、コアなデータ構造がきれいに処理できるかを検証します。

あとは、実際の実装メンバーが確定したときにプロトタイプのソースを見てもらって、こんなのを作るんでフレームワークの仕組みと、プロジェクトの概要を勉強してねと渡します。

多くの場合プロトタイプを作ったときに細かい改善点が見えますので、プロトタイプは捨てて新しいプロジェクトで組み始めたりします。インターフェースなども実際に触って検証しないとなかなか使い勝手がいいものはできないですからね。

DIの明示的指定って必要?

通常必要ありません。指定するとHot Deployが効かなくなります。

AOPって必要?

本当に理解していて、必要があれば利用してもよいと思います。同じぐらいの労力で他の解決方法があれば従来の方法の方をお勧めします。

そりゃないぞっていう実装

Dxoが複雑

Daoからロジック用のデータ構造で取得して、Dxoで画面用のデータ構造に変換。しかもロジック用と画面用で微妙にデータ構造が違う。。。

担当者が違っていて、別々に作っているとこうなるって実装ですね。しかもDxoで変換できない物があって失敗したものを詰め替えている。

ロジック部分はコード値のみを持っていて、画面部分は文字列しか持っていなくって更新時に文字列からコード値を逆変換するとかマジやめてほしいです。

ほぼ同じ構成のはずなのにカラム名が違う

A会員、B会員、C会員とあってほとんど同じカラム構成だけど少し違うテーブル設計。共通部分のはずのカラム名が微妙に違う。。。
設計者が違うのか?

Dxo(+手変換)を渡るうちに名前が変わるってのも厄介です!

モックでしか動かないコード

モックの中だけであとで必要になる値を設定しているんだけど。。。
モジュール単位で開発をしていて、動かない場合にはモックに手をいれて動かしちゃうとこうなりますよね。

総括

Teedaは非常にさくさく実装できるフレームワークだと思います。実際にDBと連動して画面を動かすってところまでがS2Daoの利点もあって、非常に手軽に動かすことができます。

まずは作って動かしましょう!

とはいえ、古のStrutsをメインで開発してきたメンバーが、古い開発規約を元に実装をするとものすごく面倒なものができあがります。サクサク感がまったくなく、ロジックをちょっと触るとTomcat再起動が必要になったりします。(とくにSeasar2.3などからSeasarを触っていたりするとね)

個人的にはJavaの古参プログラマよりは、他の言語から入ってきた人や、新人プログラマが過去のしがらみがなく使えば非常に便利だと思います。過去のしがらみがある環境の場合には、SAStrutsを普通のStrutsより楽に使えるフレームワークとして使った方がいいと思います。

あと、ここに書いてあることは結構偏っている意見なので、そのまま鵜呑みにしないでください(笑)