ディスプレイとプログラム

さて、今日は私の環境とプログラムの関係ついて話そう


世間一般ではディスプレイサイズは日々、大きくなっているようだ
私の周りでも24インチは当たり前だったりする
しかし、私は ナナオFlexScan L567 という17インチのディスプレイx3
という環境で開発を行っている
これには3つの理由があるのだが、そのうちのひとつはプログラムの書き方と関係があるので今回はその話をしよう


さて、理由だが
1.FlexScan L567は目に優しい
2.複数のディスプレイだと用途に応じて表示するウィンドウを分けておける


この二つはあまりプログラムとは関係ない
3.ソースを表示する幅を制限する


これが大事
つまりIDEを使っていたとして、そのウィンドウが1280x1024に収まる
必然的にフルHDのディスプレイなんかと比べると大幅にソースを表示しておける面積が狭くなる
これによって一度に表示できるソースの量が少なくなるので長いプログラムを書くと読みづらくなるのだ
よって一つの処理単位でやることを最低限に絞るようになるだろ


というわけで皆さんもぜひお試しあれ

マルチスレッドは難しい

フィールドの変数でリソースの解放が必要なものがあったので
finalizeメソッドで解放し忘れているときは解放するように書いておいたん


マルチスレッドの時に同一の変数にアクセスされるとそれはそれは困ったことに
なることに気がついたので
ThreadLocalな変数にしたところ
finalizeの際にリソースが解放されていないことが発覚した


finalizeはgcさん任せなのでどうやら別スレッドから呼び出されているようだ


困ったことになったので大幅な変更を余儀なくされた
1.少々回りくどいが、リソースを保持クラス(これをAとする)を保持するクラス(これをBとする)を作成
2.BにはThreadLocalでAを持たせる
3.Aには普通に変数を持たせる
4.Aのfinalizeメソッドでリソースが解放されていない場合は解放する
5.AとBを同一パッケージに入れて,Aにはデフォルトのアクセス修飾子にしてB以外からアクセスできなくする


これで、少なくともスレッド終了後にはリソースが解放される可能性を持つことになる
いつになるかはわからないがもともとfinalize自体がそんなもんなのでまあ、大丈夫だろう
とりあえず意図的に開放しなかった場合にちゃんとFinalizerさんがログをはいてるのは確認できたし

それにしても使う側からは特別な操作が一切必要なくAOP的なことやってくれればこの手のことは問題にならないのになぁ…

そういや昔、C++でnewとdeleteは勝手にやってくれるってプログラム書いたな…
でもあれはdeleteのタイミングをこっちで制御できるからうまく動くだよなぁ…
そもそも今回のリソースの解放と違って明確にdeleteするべきタイミングが分かってる前提だし…


あ、でもデストラクタ呼び出されるタイミングはわかってるからそっち使う側でよろしくやればうまくいくかも(え?オブジェクト指向チックじゃないって?知るか!!)


というわけで今日の結論
GC嫌い、信用できない。でも、プログラマは人間なのでもっと信用できない

Javaに手軽さがほしい

javaからdbにアクセスしてると、結構DRYじゃないプログラムを書いている自分がいることに気づく
あと、いちいちBeanを作るのが面倒
何でも最近の動的型付け言語は素敵らしい


というわけで安全性を犠牲にして、手軽なDBアクセスのクラスを作ってみた
結果一行を
Mapの形にする
column名がkeyで値がvalue
でこれのListを返す
キャストしたりとか面倒だが・・・
select, insert, update, deleteのメソッドを用意し
sqlとインジェクション対策にPreparedStatementにセットするパラメータを
引数で渡す(ちなみにselect以外は同じ処理でかけるのでupdate, deleteはinsertを呼び出してるだけだったりする・・・)
問題なのがコネクションとトランザクション
finalizeメソッドをオーバーライドしてコネクションのクローズを書くが
gcのタイミングが読めないのでfor文とかでコネクション取得し続けると
パンクする(System.gc()を呼べば問題はないが・・・)


というわけでコネクションクローズ用のメソッドを追加
finalizeでこれを呼ぶが基本的には手動でcloseしてもらう


こんな状態じゃトランザクションなんて当然無理なので
ここだけは手動で
代わりと言っちゃ難だが、トランザクションの有無は選択できるようにした


あとはサブクラスで具体的にコネクションを取得する方法を定義してくれれば使える


う〜ん・・・まだ面倒くさいなぁ・・・
だれか事前の設定とかAOPとかなしでPOJOな感じでこの辺うまくやる方法知ってる人は教えてほしい

昨日の続き

どうやら機能は相当眠かったらしいね


・コネクションのクローズについて
1.各sql発行の前にコネクションがnullなら取得する
2.sqlの発行
3.トランザクション処理中でなければコネクションクローズ


トランザクション処理中は?
1.トランザクション処理開始時にコネクションがnullなら取得
2.トランザクション開始
3.dbアクセスの処理
4.トランザクション終了
5.コネクションのクローズ


これで手動でコネクションの取得とクローズはしなくてよくなった


あとはトランザクション処理を始めてcommitもrollbackもコネクションのクローズもしない人がいた場合だが
こればっかりはどうしようもなさそうなので
finalizeメソッドでログをはいておくことにした
とりあえずこれでそんなことしてる輩でもいつかは気づくはず・・・

FAQ?

とりあえず今起こった出来事


Q.プログラム中に書かれたSQLが読みづらいです。改行とかインデントとかできませんか?
A.SQL文をファイルから読み込んでみましょう。


Q.SQLに変更がありました。再コンパイルが面倒です。
A.SQL文をファイルから読み込んでみましょう。


というわけで、某システムはDBの設計の問題でSQL文が数十行から百行以上といった複雑ものになります。
ほとんどは副問い合わせか結合ですが、whereがひどいことになることも多々あります。


また、カラムやテーブルが追加されることも稀ではありません。


というわけで、このDBにアクセスするアプリのSQLを整形した形で別ファイルに保存しておくことにしました。
こうすることで、読みやすいですし、コメントも入れやすいです。


ただ、ファイルアクセスの管理が面倒です。
今回は単体起動のアプリで複数人が同時に同一ファイルを読み込むことがないものなのでやってみます。
まぁ、プログラムからファイルに書き込むことはないのでどっちにしろ問題なさそうですが・・・