- ベストアンサー
効率よくリソースを読みこむには
複数ウィンドウを開きますが、メニューはすべて同じ文字列を使用します。 メニューの文字列をリソースファイルから ResouseBundleを使用して取得したいのですが、 複数のウィンドウすべてでいちいちファイルを読みこんでいては無駄になるとおもうので、一度読みこんだらあとはそれを使いまわせるようにしたいのです。 staticとかfinalを使って可能かとおもったのですが…。 どうにも頭がこんがらかってしまい、うまく出来ません。 おなじような設計をしたかたがいらっしゃいましたら アドバイスをよろしくお願い致します。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
先ず初めに、、、 色々と設計の仕方はあると思いますが、静的アクセスの利用(= static 宣言)というのは、一つのアプローチとしてよい方法だと思いますよ。 頭がこんがらがっているとのことですが、デザインパターンのSINGLETONパターンを応用すれば設計をまとめることができると思います。 具体的には、 ・リソースバンドルを管理するためのクラスを用意する ・そのクラスにリソースバンドルインスタンス取得用のstaticメソッドを用意する 例えば、雰囲気だけ書きますと以下のようなります。 ----------------------------- public class MyResource { private static MyResource instance = null; java.util.ResourceBundle rb = null; protected MyResource() { // リソースバンドル rb の初期化処理を行う } public static java.util.ResourceBundle getResourceBundle() { if (instance == null) instance = new MyResource(); return instance.rb; } } 他のクラスからリソースバンドルを利用するときには java.util.ResourceBundle rb = MyResource.getResourceBundle(); で取得できます。 ----------------------------- と、このようなクラス設計をして、リソースバンドル使用側で確実にMyResource経由でリソースバンドルインスタンスを取得するようにすれば、一つのリソースバンドルインスタンスを使いまわすことができるはずです。 ここからは余談です。 既にデザインパターンについてご存知ならば失礼いたしますが、、、 デザインパターンという、一般的な設計手法をまとめたものが存在します。 デザインパターンは設計を考える上で非常に有用ですし、興味深いものです。 # まるで手品を見ているような、素晴らしいデザインパターンがいくつも提唱されています。 是非デザインパターンを勉強されることをお勧めします。
その他の回答 (2)
- stardust
- ベストアンサー率44% (8/18)
> いま作ろうとしているシステムがものすごく遅くなりそうなので、 > 少しでも早くできそうなところは短縮するようにとの > 命令がでてしまいました。 大変そうですね。 どういうシステムを作られているのか判りませんが、 データベースを扱うシステムでは、注意して設計しないと システム全体のパフォーマンスを著しく低下させることになります。 後、今すぐ思いつくのは ・長い文字列を(テキストエディタ並に)扱う場合はStringBufferを使うこと ・プロセス間通信は時間を食うので、無駄な通信を極力減らすこと で、パフォーマンスをアップさせることができます。 tontoto さん、これからも頑張って お互い勉強していきましょう!
お礼
ほんとうにありがとうございます。 参考にいたします。 実は重いのはGUI部分なのです。 Swing使ってるので…。 しかもさらにその下には通信が走って…。ぅぅ。 データベースは扱わないのですが…。 ユーザさんに強制終了されかねないので、 ちょっとでも早く…。とおもっています。 プロセス間通信…。 亀のようにのろい歩みですが、頑張って勉強していきます。またよろしくおねがいします。 今回は本当にありがとうございました。 …このシステムて20ポイントが最高なんですね…。たりない…。
- stardust
- ベストアンサー率44% (8/18)
tontotoさん、こんばんは。 確かにtontotoさんが補足で書いておられる方法のほうが断然速いですね。 簡単なサンプルを書いて処理時間を計測してみました。 ------------------- 環境はPentium3 450MHz のノートパソコン、JDK1.2.2。 10万回の文字列取得処理を10回繰り返した平均値を計測しました。 tontotoさんの方法では、1ミリ秒以内。 前回の私の回答の方法で、約400ミリ秒です。 ------------------- クラスメンバとして持たしてしまえば、メモリ上の位置が決まっているのに対し、 リソースバンドルは逐一、キーから値を検索し、新しいStringインスタンスを生成するのでこのくらいの差はつくのでしょうね。 フレームのメニュー文字列を取得する目的ならば、無視できる差ですよね? となると、後は実行速度とメンテナンス性の兼ね合いでしょうか。 それはtontotoさんのお考え次第です!
お礼
ああ、速度の実験まで…。 なにからなにまで申し訳ありません。 本当にありがとうございます。 stardustさんに教えていただいたSINGLTONのやり方で 取得するStringインスタンスも シングルトンのクラスのなかにかけないものかと思ったのですけれど…。 (getMenuStringメソッドとか定義してstaticなStringを返すように…) これはこれでごちゃごちゃしてるように見えるかな…。 と考えています。 10万回の文字列取得を10回でも400ミリ秒ということですので、 これなら性能的にそんなに影響ないでしょうし、 ソースも綺麗なのでstardustさんに教えていただいたやり方でやろう、 と個人的に思ったのですが。 いま作ろうとしているシステムがものすごく遅くなりそうなので、 少しでも早くできそうなところは短縮するようにとの 命令がでてしまいました。 そこで結局今回は Stringもstaticにするやり方をとることになりました。 でもすごく役に立ちました。 これからも役立つ知識教えていただきましたし…。 本当に本当にありがとうございました。
お礼
ありがとうございます!お礼が遅くなって申し訳ありませんでした。 このお礼に気づく前に以下のように無理やりソース組んでから気づきました。 そこで「stardustさんの例ではResourceBundleを使いまわしてるけど、 ResourceBundleから取得した文字列そのものを使いまわすほうが早いだろうか」 (つまり、リソース読みこみの時間はResourceBundleを得る時間が長いのか、 そこから文字列を得る時間は無視できるほど小さいのか…?) という疑問がわいてきてしまってお返事が遅くなりました。 実験して確かめてからお返事しようと思っていたのですが、 なかなか時間が取れなくて…。 でも良く考えて見たら、ResourceBundleのインスタンスをreturnする メソッドじゃなく、それぞれのStringをreturnするメソッドを作れば 文字列そのものを使いまわすことがちゃんとできますよね。 なので、ここからは純粋に興味なのですけど、 もし理論的に上記の疑問の答えがおわかりでしたら 申し訳ありませんが教えていただけませんか? また、近いうちに実験してみるつもりなので、 その結果がでてからこの質問を締めきりたいとおもっています。 ポイントの発行など、しばらくお待ちください。よろしくお願いします。 それから「デザインパターン」。 言葉は知っていたけど難しいことなのかと思って食わずぎらいしていました。 これを機会に少し本をみてみたら、 stardustのおっしゃる通り、すばらしい例が載っていて、感動しました。 ものすごく役に立ちそうです。 ほんとうにありがとうございました。 /*今となっては間抜けなソース*/ public class A { //リソースから取得する文字列 static String strA; static String strB; static String strC; static String strD; static String strE; /** *コンストラクタ */ public A() { //文字列まだ読みこんでなかったら if(strA == null ) { //文字列リソース読みこみ getMyResource(); } System.out.println("strA="+strA+"...."); } /** *リソース読みこみのためのメソッド */ static void getMyResource() { try { java.util.ResourceBundle myResource; myResource = java.util.ResourceBundle.getBundle("myResource"); //文字列読みこみ strA = consoleResource.getString("a"); strB = consoleResource.getString("b"); strC = consoleResource.getString("c"); strD = consoleResource.getString("d"); strE = consoleResource.getString("e"); }catch (java.util.MissingResourceException e){ } } }