2012-03-29 6 views
4

フィールドとして値を置くと、この値がオブジェクトの状態を表す場合にのみ意味があります。意味があるときはいつでもメンバ変数をパラメータメソッドより優先したいですか?

場合によっては、この「ルール」を避けるべきなのかなと思います。ここで

たとえば、このクラスを考える:

public class DbCar { 

    private ResultSet rs; 

    public DbMapper(ResultSet rs) { 
     this.rs = rs; 
    } 

    public Car buildObject(){ 
     //.....does some mappings, then returns the builded car .... 
    } 
} 

だから我々は、ResultSetがメンバ変数として格納され、DbCarなどのあらゆるDbMapperはJDBCクエリから取得したResultSetを操作するので、それは理にかなっていることがわかります。

我々は次のようにのように見える、発信者だろう:

while (rs.next()) { 
    items.add(new DbCar(rs)).buildObject(); 
} 

をしかし、現在のクエリが15000件のレコードを返したことを想像してみてください。

DbCarオブジェクトが> 15000個のインスタンスにまとめられました。

私の質問はガベージコレクタが十分に効率的なので、この膨大な数のインスタンスについて心配する必要はありませんか?この場合

public class DbCar { 

    public Car buildObject(ResultSet rs) { 
     //.....does some mappings, then returns the builded car .... 
    } 
} 

、DbCarの単一のインスタンスを(現在のスレッドで、現在の方法で)になります。次のようにこれらのすべてのインスタンスを回避することはもちろん

は、我々は、コードをリファクタリングすることができ呼び出し元は次のようになります。

DbCar dbCar = new DbCar(); 
while (rs.next()) { 
    items.add(dbCar.buildObject(rs)); 
} 

どのような解決方法を選択する必要がありますか?より洗練されたコードやガーベッジコレクタを信頼し、ローカルパラメータメソッドを使用したより手続き的なコーディングスタイルのようなコーディング?

DbCarクラスは、エレガントな小さなメソッドにその「ビルド」メソッドを分割することを想像し、難しい選択を行うために

、例えばのような特定の責任に捧げそれぞれ1:

「buildEngine」、「buildDoors」など...ローカルパラメータを選択する場合、これらのメソッドにResultSetを渡さなければならないでしょう。退屈でレッドダントなのですか?

+0

私がダウンして手、パラメータとしてResultSetを渡します。 –

+1

2番目のケースでは、 'DbCar'オブジェクトを作成する正当な理由がない限り、' buildObject'を静的にするだけです。 – trutheality

+0

@trutheality DbObjectがDbObjectを継承していることを想像してください(ほとんどの場合)。 resultSetの操作を簡単にする便利なメソッドをリストしたものです。静的だった場合、このスーパークラスから利益を得ることはできませんでした。 – Mik378

答えて

2

これはGCの問題ではありませんが、アプリケーションの要件に完全に従います。

前回のプロジェクトでは、アプリケーションが4秒ごとに150000 DTOオブジェクトのようなものを作成している、Solarisサーバー(10GBのRAMが必要)で動作する非常に大きな「ほぼリアルタイム」のアプリケーションの開発に携わっていました。そう。一見するとこれはGCには何の影響もありませんが、一部の勤務時間後に、ユーザーはハードウェアからデータが失われるというソフトウェアに不満を持ち始めました。私たちは長い時間をかけて問題を調査しましたが、GCが完全なCPUを使用して未使用のオブジェクトをクリーンアップしてアプリケーションを1秒間ハングアップしたように見せていたことがわかりました(信頼できます。 1000ドルより)

+0

非常に明確で興味深い説明:)ありがとう – Mik378

2

ガベージコレクタはこれをうまくやり遂げて、最も明確な実装を選択することができます。後でこれがパフォーマンス上の問題を引き起こす場合は、リファクタリングすることができます。実証された理由がない限り(これがボトルネックであることを示すプロファイラのように、速くするために明快さを失わなければならない場合を除いて)、常にクリーンな実装を行うべきです。

GCがこれをうまく処理できないと私は驚いています。

4

2番目が優れています。 15000オブジェクトはガベージコレクタには何もありませんが、結果セットオブジェクトにはハングしないことをお勧めします。その理由から、#2はより良いです。

+4

+1 - 結果セットのような一時的なステートフルオブジェクトにぶら下がっているだけで、問題が発生していることを尋ねています。 –

0

あなたの特定の問題は、機能的な設計の問題です。通常は、プログラムを設計するときにガベージコレクタについて心配する必要はありません。 GCで考えなければならないのであれば、非常に少ないメモリを使用するための非機能的な要件を持つアプリケーションに取り組んでいると思うか、非常に大きなアーキテクチャを最適化していると思います。それはあなたの場合ですか?

このようなテンプレートを実装するためのパターンがあります。私は、例えば春のJDBCテンプレートを参照のうえだ:

http://static.springsource.org/spring/docs/2.0.x/reference/jdbc.html

+0

私は投資銀行で働くので、データベースは巨大です。したがって、多くのメモリが割り当てられていても、コードが十分に最適化されていないと予期せぬ動作が発生する可能性があります。 – Mik378

+0

私はまた、大手銀行の建築を手がけています。 SpringのORMと連携し、JDBCTemplateを使用することで、結果セットをプリミティブ型やオブジェクトにマッピングできるようになりました。 Springを利用できない場合は、Spring Template ORM Patternに対応する2番目の方法が広く使用されているパターンであることをお勧めします。乾杯。 –

関連する問題