サービスクラス

ここで言うサービスクラスってのは Web アプリサーバのビジネスロジックを担当する部分のクラスの事なんだけど。これを作る意味って何なのかって余り深くは考えてなかったなあって思った。
サービスクラス自体と入力クラスと出力クラスの全てを POJO にする事で、Web フレームワークや画面処理から切り離せて移植性が高まる。POJO なので jUnit がやり易い。ビジネスロジック処理を共通利用出来る様になる。Web フレームワークの所謂アクションクラスを画面処理だけに出来る。後々に処理を負荷分散する仕組みに組み込み易くなる。そんな感じかなあって思ってる。インターフェイスを作って IF と実装の分離をしたり、シングルトンにしたり、AOP を適用したり DI を適用したり、そういう小技の対象として使い易いってのもあるな。
だけどサービスクラスが DB アクセス等々のフレームワークに依存している事に変わりは無いんだよな。それとかバリデーションは Web フレームワークの方でやってるから、移植性は実際には確保出来ていない所が多い。もし本気で移植性を考えているのなら、バリデーションはサービスの中で行わなくてはならない。バリデーションって言っても完全に画面制御に関する項目であれば、サービスクラス内で行う必要が無い。というか逆にやってはいけない気がする。だけど商品コードという項目に入力されている値が正しいかどうかをチェックする処理は、仮令それが単項目チェックであってもビジネスロジックとしてサービスが持っていないと移植性を確保出来ない。
俺には現場の連中の「サービスクラスに求める物」が支離滅裂としている様に思える。俺自身も真面目に考えていなかったんだけど…。俺は java の本を全く読んでないからね。C++ ならアジソンウェスレイのプログラミング言語 C++ 第 3 版を途中まで読んだんだけどね。ネイティブコードを吐き出す C++ は最高ですよ。C++/CLI はどうかなって思うけど。C++ に比べると java って糞だよなあ思ってしまうけど、今はその話は関係無いな。
C++ をやってた頃は例外処理は重いから絶対に使わない主義だったんだけど、java ではエラーは例外で返す物って事で例外を多様する様になった。だけど例外ってのは例外を投げた時点で後続処理を実行出来ない欠点がある。要は複数のエラーが発生した場合でも処理を継続しなくてはならない場合に困るって事だ。そういう場合は List とかでエラーを返す必要があるんだけども、それってダサいなあって思っていた。出力クラス又は入力クラスの中に List のフィールドを持たせて、そこにエラーを詰め込む感じ。非常にダサい。でも結局はそれしか無いんだよなあ…。エラー無視の思想ならばログに吐いて、呼び出し元にはエラー群を返す必要は無いんだけど、呼び出し元がエラーを把握しなくてはならないからな。例外にエラー用リストを持たせてそこにエラー群を詰め込むのは、正常な戻りを返せなくなるし。例外に正常な戻りとエラー用リストを入れるのは有り得ないしなあ。サービスクラスと他クラスの結合度を少し強めても良いのならスレッドローカルを使う手もあるな。
俺が最初に経験した Web の java のプロジェクトでは、サービスのエラーはチェック例外を投げる事で対処する方針だったんだよな。アレってのは良く考えるとちゃんと理由があったのかも知れない。あの職場の場合はサービスのメソッド呼び出しに対して AOP で DB のトランザクションが生成されてたんだよ。そして例外に反応してロールバックしていた。だからエラーを例外として返す事に重要な意味があった。
今の職場の場合は致命的なエラーの場合は例外を発生させるけど、そうじゃ無い場合は例外を使わない方針なのかも知れない。例外はフレームワークの共通処理でのみハンドリングするという割り切った考えっぽい。それともあのプログラマの個人的な経験からの癖かも知れないけど…。確かに今のプロジェクトのサービスクラスはトランザクションとは無関係だ。
それと現場のプログラマが書いたソースコードを見て驚愕した事があってさ。サービスクラスが返すエラー情報として HTML の ID が含まれていてさ。有り得ない糞コードだなあって思ったんだけど、良く考えてみると逆に考える事が出来る。サービスクラスが返すエラー情報に合わせて HTML を書いたんだって…。確かに物としては先に HTML があったんだけどね。HTML を完全にサービスクラスに依存させて書いているってのも微妙っちゃ微妙なんだけど、アリだとは思った。でもさあ入力クラスのメンバ名と画面の HTML の ID が全く別物でさ。どうしてサービスクラスが入力クラスのメンバ名を無視して HTML の ID と同じエラー項目名を返すのか不思議でならないんだよな…。
俺は画面に関する処理は全てアクションとかに記述すべきだって思ってたんだけどさ。画面のエラー項目を赤く表示するとか。画面に表示するエラーメッセージを書くとか。だからサービス内に画面表示するエラーメッセージ ID が記述されている事に非常に違和感を感じた。でもログに出力するメッセージ ID と画面に表示するメッセージ ID が同一の体系である事を考えると、サービスクラスで画面に表示するメッセージ ID をエラーリストに詰めるのはアリな気がした。そういう思想で書いてたのかなあ。でも流石にエラーメッセージの日本語がサービス内に書かれているのはおかしいかなあ…。画面表示項目を赤くする為に HTML の ID を返す事に関しては、前述の理由で我慢出来るかもだけど、エラーメッセージの日本語は微妙だなあ…。でも各画面に対して画面に密着したサービスが必ず 1 つは存在するって考えれば、そのクラスに限定すればやっても良いのかなあ。
そうすると結局何が目的なんだって言いたくなるけど。jUnit も使って無いしさ。jUnit を使えるよって言える状況が欲しいのかなあ。移植性は余り無いし。アクションをすっきり出来るって言っても、アクションに画面に関する処理であるエラーメッセージとかの処理を書けないデメリットのが大きい気がするし。負荷分散する気なんて無いし。共通利用は出来ないし( 全く不可能では無いが )。
現場の人間は「アクションはすっきりさせたいんすよ」って言うんだけど「それに何の意味がある?」「お前の理想って何?」ってのが俺の率直な感想。俺も悪いんだけどさ。もっとちゃんと考えて置けば良かったなあって。