なんとか最終課題の提出とプレゼンが終わりました。
合否判定はずっと先ですが…。
とりあえずこれで講師への技術質問が解禁になったので、気になってた事を軽く整理してもらいました。
まず、図というか、こんな感じで層を分けるとします。
Actionクラス | ビジネスロジックのクラス | DAO | DB
Actionクラスから左側は書いてませんがStrutsです。
今の段階ではビジネスロジックをActionクラスに書いてます。
上記の図に従うと、Actionクラスがビジネスロジックに依存しない形で実装する事になります。
同様に、ビジネスロジックとDAOも依存関係がないようにします。
こうすることで、フロント側に変更がかかった場合、つまり、Strutsじゃなくなった時でも手が打ちやすい。
同様に、DB周りが変わった場合は、DAOクラスに手を入れるだけでよい事になります。
なるほど、なるほど。
で、ここで登場するのが、各クラス間のオブジェクトのやりとり、つまりデータのやりとりをするためのオブジェクトが必要です。
その型にあたるものがEntity(ValueObject)、DTO。
型というと漠然としていますが、DB等からSELECTしてくると、複数レコード取得したりします。
この時の1レコード分のデータを詰めるものがDTO。
DTOには、DBからSELECTしてくる項目を定義している感じです。
複数レコード取得してくる場合は、Listにぶち込むわけですな。
一方で、Entity(VO)は、Actionとビジネスロジックの間でやりとりされるもので、セッションやリクエストスコープに詰めるもの、と考えるようです。
Action <=> ビジネスロジック : Entity(VO)
DAO <=> DB : DTO
あれ、「ビジネスロジック <=> DAO」は何だっけ???
まぁ、あれだ。
より生データに近いものは、表示するために遠いデータ。
たとえば金額とかだったらint型でDBに入ってるので、DTOにはint型で入ってる。
これを表示するために近い形で持つEntityでは、金額のフォーマット(¥999,999)とかで、Stringで入ってたりするのかな。
このあたりの変換や計算をするのはビジネスロジックに任せる。
Actionクラスは結局ビジネスロジックが処理した結果を元に、画面遷移やスコープに詰めるだけって事だね。
ひーこら言いながら取り組んだ課題だったけど、ここまでの考え方を理解した瞬間、作り直したい感が満載でした
まぁ、今の知識ではActionクラスとビジネスロジックとの依存関係を断ち切る事ができないのも分かったんですけどね。
これを解決するために、DIコンテナのお話が出てくるようなんで、またお勉強です。
今時点では、Actionクラスのexecute()内には
コレクション型<何某> hehe = new コレクション型<何某>();
ビジネスロジック型 hoge = new ビジネスロジック型();
hehe = hoge.getFuga();
if( hehe == null){
mapping.エラーページ
}else{
httpsession.setAttribute(”HEHE”,hehe);
mapping.正解のページ
}
みたいな事をするのが精いっぱいですかな。
結局今日は、Actionにベタ書きしていたSQL部分を切り出して、DAOに分離させるっぽい事にチャレンジ。
まず、抽象クラスとして、コネクションをはるところ、executeQuery()、executeUpdate()、ロールバック、コネクションやステートメントのクローズを準備。
準備といっても、Google先生に教えてもらったサイトからちょいと拝借してカスタマイズ。
で。
ここから先は、どういう単位で継承クラスを準備するか。
この部分は、いろいろ議論が及ぶところですが、正直まだよく分かんない。。。
Entity単位に準備すれば良さそう、というのはなんとなくわかります。
ていうか、そもそもEntityってどういう単位として考えるか。
が、勘違いしてはいけないのが、画面=Entityではないということ。
そして、TABLE=Entityでもないということ。
と、今は考えています。
きっと似たような問い合わせをする画面が複数あったりするわけですよ。
画面単位で用意すると、似たようなSQL文があちこちのDAOに散らばる事になります。
今思いついた事ですが、ある程度汎用的な問いあわせ…つまり、AというテーブルとBというテーブルを結合したCというViewっぽいものを、全カラム取り出すEntityをざっくりと用意します、と。
これを、必要に応じて各Actionから利用する。
これなら、Aというテーブルのa、bのカラムを利用するAction、a,cのカラムを利用するActionがあるとすると、同じEntityとみる事が出来ます。
テーブルが複数になっても、Viewとしてみれば問題ないでしょう。
で、今日は結局Actionから分離させる、DAOの抽象クラスを作って、分離させた部分を継承クラスへ実装する、にとどまりました。
つまり、DAOの継承クラスの中に全部放り込んじゃいました(汗
まぁ、アプリケーションの規模によってはこういうのもありじゃないかと思いますが、ソースコードが500行近くになってきたので、そろそろ分割した方がいいかと思う今日この頃であります。
—————-
さて、もうひとつ未解決があります。
例外クラスのExceptionとSQLExceptionを、それぞれをそれぞれの独自例外を用いてActionクラスでcatchさせるには…?
単純に考えたのが、Actionクラスのexecute()内を全てtry~catchで囲ってやって、SQLException→Exceptionの順にcatchしてや…。。。。
あれ、なんかおかしくないかな?
SQLExceptionは、基本的にはDAOクラスで発生するので、DAOクラスでcatchしたら、独自例外にスローする。
DAOを利用しているActionクラスでは、独自例外をcatchして画面遷移に利用できます。
どっこい、Exceptionはあちこちで発生…というか、全ての検査例外の親クラスなのでActionクラスで発生したExceptionで独自例外に渡してやるっっていっても、Actionクラスからはどこにスローするの???
スローできたとして、何が処理するの?
んー、tomcatかしら。
struts-configに、global-exceptionを定義できるので、Exceptionをcatchして独自例外がスローしたものは、こいつがひらってくれるのか。
でも、Exceptionよりも先に発生したSQLExceptionは、スローさせてきた結果、親クラスであるExceptionに持っていかれちゃったりしないのか。
DAO、独自例外、いずれももう少し試してみるだけの時間もなく時間切れになりそうだなぁ。
毎度、オブジェクト指向にどっぷりな生活を過ごしています。
先週後半から、最終課題に突入しています。
一応、習得内容から実装するのですが…講義の内容と課題の内容がぶっ飛んでます。
1、2教えたから、残りの9は自分で考える、もしくはGoogle先生によろしく!なんていう状況です。
しかも最終課題中は、技術的な質問や周りの人との相談もNGなんですよね。
まぁ、こういう自力でしんどい思いをするからこそつく力もあるんでしょうけども。
で、つい先ほど力尽きて帰宅したのですが。
実装できてないのがDAO。
Strutsを使ってますが、現状Actionに直接SQL書いちゃってます。
考え方そのものは理解できるのですが、実用アプリ実装レベルになると、手が止まるんです。
DAOの作成単位とか、いまいちピンとこないのです。
そもそも研修内で触れてないところだし!
それってどーなん!?
さて。
極端な話、SELECTのDAO、UPDATE、DELETEのDAOの2つだけでもいいのか?
ステートメントを渡して、excuteQuesry()か、executeUpdate()のどっちかを実行するだけ。
あぁ、これじゃだめだ。
たとえば、極端な話特殊なDBに変更になった場合や、テキストファイルなんかになったら改修箇所大杉。
DAOFactoryみたいなクラスを作って、問い合わせ単位でアクセサメソッド作る方がいいか。
問い合わせ、更新、削除対象となるオブジェクトの参照値を渡してやる。
問い合わせの場合は、戻り値は要考慮。
DAOクラスでSQLExceptionが発生した場合はどうなるのか。
他の参加メンバーが、FilterでSQLExceptionをcatchしてやろうとしていました。
どっこい、ActionクラスからSQLExceptionをスローしても、いろいろ経路を通ってくる間に、ServletExceptionとかExceptionになってしまうとの事。
上位層のビジネスロジックにまでスローしないようにするには、独自例外を作ってそいつにスローするって事になるわけですか。
なるほど。
それで課題の中に「SQLExceptionを継承した独自例外を作る事」ってーのがあるんだな。
ていうか、明日しかないんですが。
現状動いているので、手を入れたくないんだよなぁ。
データアクセスって結構肝じゃないか。
プレゼン直前に動かなくなるって、ありえねーしなぁ。
ってか、考えるなら会社でやれっつーの。
帰ってきて服脱ぎ散らかしたまま、布団に寝そべってノートPCつついてググってるわけで。
まぁ自宅だからリラックスして頭が回るってのもあるんだけどね。
なんていうか、もう一日だけ余分に納得いくもの作れそうなんだけどなぁ。
まぁ、Strutsも枯れた(熟成された)フレームワークなんだけど、決して効率のいいものじゃないってことは分かったかな。
やっと梅雨入りしたって感じの蒸し暑さにやられ、昼過ぎまで家でゴロゴロ、うだうだ。
とりあえず、GWあたりから乗りっぱなしだった事が随分気になっていたんで、ヨシダに行って洗車してきました。

…このような事はありません。
男臭く、セルフサービスで、汗まみれになりながら洗ってきました。
そういえば、確かに海パンで洗車すると水しぶきとか気にしなくていいですね。
絶対やりませんけど。
で、5月のタイヤ交換時に某大阪のお店で指摘されたチェーン交換の段取りをするべく、いろいろと準備してたんですがね。
せっかく手元にレースベース車の純正スプロケと、AFAMのスプロケがあるので、重さを比べてみました。
まず、純正スプロケ。

546gです。
500mlのペットボトル以上もあるんですね。
円盤型してるので、持った時の場所で感じ方も違うんですが、自分としてはもう少し軽いものと思ってました。
さて、一方AFAMのスプロケは…

275gです。
純正のちょうど半分ですね。
手で持ち比べて、明らかに違いは分かるんですが、半分くらいかな?と思ってたんですが、ドンピシャとは。
軽いのはいいんですが、耐久性はどうなんでしょうか。
アルミにハードアルマイト加工のAFAMに対して、SUNSTARは超超ジュラルミン。
AFAMは表面が終了したら一気にサヨウナラなイメージです。
よく考えてみたら、でっかいバイクで社外スプロケに交換するなんて何年ぶり?って感じなのです。
交換はちょっと先になると思いますが、30,000km近く放置な足周りなのでよき方向に行く事は間違いないでしょう。
カスタムではありませんが、消耗品をリフレッシュするのは地味な楽しみであります。
今週頭には渋い天気予報でしたが、二日前くらいに一転して快晴の予報に。
予報通り、梅雨入り前の最後の快晴となりました。
とりあえず、目的地は津山と美作の間にある勝央町にあります滝川食堂。
前回は、去年の秋にりゅうちゃんと2人で。
blogはこちら
今朝の寝起きはかなりローテンションで、起動にかなり時間がかかった上に、岡山市内を抜けるのに思いのほか時間がかかったり、葬儀屋の前を通る時にちょうど出棺のタイミングにはちあわせてしまって超渋滞してたりしまして、予定の20分遅刻(爆
まぁ、関西からも遅刻の常習者が例によって遅刻したようでしたが(笑
で、今回は7名の参戦となりました。
開店前から押し掛けるのが当たり前のような感じですが、今回も開店前に入店。
既に2組のお客さんがいらっしゃいまして。
そして、僕らが到着してほどなく、8名のバイク乗りのおじさま連中が来店。
やっぱり知ってる人は知ってる名店なんですね。
で、とりあえず大将に注文はお任せすることにしました。
で、おばさんには冷たい麦茶をいただき、「めし」の注文を。
迷わず「めし大」を頼む使途。

そして麦茶ではなく発泡している麦的な飲み物が!?
そうこうしてる間に、大将がとなりの鉄板で焼き焼きしております。
ホルモン、シンゾウ、レバー、かしわ、もつ…これに玉ねぎとピーマンが入りまして…。
来ました!

ホルモンから出た油が鉄板の上で弾ける音。
オリジナルブレンドの秘伝の味噌ダレが焦げたにおいが鼻をくすぐります。
明らかにうまそうな焼け具合。
口に運ぶと、なんとも言えない歯ごたえ、プリプリとした触感。
オンザライスせずにはいられない、味付け。
ここまで五感を刺激する食べ物があるだろうか。
大袈裟に書いてますが、これマジっす。
お持ち帰りもできるんですが、大将が焼いてくれたそばで食べるのがいいんです。
で、7人でこれくらい食べました。

しばらく黙々と言葉を発さず食べる時間がありました。
相当うまい証拠ですわ。
めし大を頼んだ約2名は、若干走行に支障をきたしそうな感じでしたね(笑
僕は中を頼みましたが(だから、大食キャラは卒業だっつーの。)
まぁ、このホルモンでご飯が進まないわけがないのです。
さて、ホルモンにこの上なく満足した後は、デザートをご所望で。
あわよくば、軽く走った上でのデザートご所望で。
天気もよろしいですしね。
でもでも、Zガンダムみたいっていう使途もいたんですが、これは帰りに寄ろうって事になりまして。
ということで、道の駅奥津に寄ったり、給油STOPしたり、超ぐにゃぐにゃ道をひたすら走って到着。
ここで

これを食べました。

ここのソフトクリームは甘すぎず、絶妙な軽さがポイントです。
しばしのんびり。

明日から梅雨入りとは思えないお天気です。

ここに来るのは僕は2回目なんですが、走行前に地図をガン見しただけでよく来れたなと思いました。
覚えてるもんですね。
道中、鬼太郎が描かれたのバスがいたりするあたり、鳥取だなぁと感じます。
さて、忘れちゃいけないミッション。
次はZガンダムなんですが、現在時刻から考えると、ちょっと厳しいお時間に。
せっかく来たのに、シャッター降りてたら残念じゃないですか。
いや、それはそれでオイシイ状況?だったり。
ということで、おとなパワーで合理的に高速道路を利用。
ええ、現在地 to 目的地が直線だったもんで。
で、1時間弱でZとご対面。

もう写真載せるのいいよね、ってくらい載せてますね。
さて、晩御飯のお話が始まります。
僕が「今日は岡山県から出ません!」と強い決意を表したからかどうかは分かりませんが、岡山市内で晩御飯する事に。
いつも帰り道にしている道を先導しまして、真っ暗になる前にお店に到着。
3人と4人で別れまして、3人テーブルのご注文はこちら。

メニュー覚えてないです(汗
生ハムのサラダ、明太子と鶏肉とごぼうのパスタ、コーンとツナの冷たいパスタ、茄子とソーセージ、きのこのピザ。
ああ、とんでもなくうる覚え…。
帰り道は2号線+ブルーラインor高速道路って感じで、岡山ICが意外に近いという事実を伝えるとあっさり高速道路をチョイス。
まぁ、2号線もすぐそこだったんですけどね。
ブルーラインは真っ暗闇だし動物出るし、虫は張りつくし、この時期、この時間は結構地獄を見ますんで。
最後の給油と、岡山ICまでご案内してByeしました。
相変わらず食ってばかりですが、結構距離も走ってましたね。
食って良し、走って良しの、大変満足な一日でした!