2017-11-22 6 views
0

私は複雑なオブジェクトをメモリに保持しているので、変更しないでください。オブジェクトが最初にインスタンス化されたときにフィールドのいくつかが初期化され、実行時にいくつかの呼び出しコードパラメータに基づいていくつかのフィールドが決定され、更新されるテンプレートとして機能します。ディープコピーのパフォーマンスへの影響

この例を考えてみます。

FooTemplateがメモリにロードされたオブジェクトです。呼び出し元コードには、このオブジェクトの更新バージョンが必要です。更新されたバージョンには、サービスセンターのリストが表示されます。リストの内容は、クライアントコード(この場合は呼び出し元の国)のいくつかのパラメータによって決まります。 【にcompanyNameを

FooTemplate:

class Test { 

    public static void main(String[] args) { 

     Caller[] callers = {new Caller (CountryCode.US), 
       new Caller (CountryCode.US), 
       new Caller (CountryCode.US)}; 

     for (int i = 0; i < callers.length; i++){ 
     System.out.println(getFoo(callers[i])); 
     } 

    } 

    public static FooTemplate getFoo(Caller caller) { 

     FooManager fooManager = FooManager.getInstance(); 

     FooTemplate fooTemplate = fooManager.getFoo(); 

     if (caller.getCountryCode() == CountryCode.US){ 
      fooTemplate.getServiceCenters().add("Seattle"); 
      fooTemplate.getServiceCenters().add("Boston"); 
     } 
     if (caller.getCountryCode() == CountryCode.GER){  
      fooTemplate.getServiceCenters().add("Munich"); 
      fooTemplate.getServiceCenters().add("Berlin"); 
     } 
     if (caller.getCountryCode() == CountryCode.FRA){  
      fooTemplate.getServiceCenters().add("Paris"); 
      fooTemplate.getServiceCenters().add("Lyon"); 
     } 

     return fooTemplate; 

    } 
} 

これは以下の出力を生成する:

public class FooManager { 

    private static final FooManager fooManager = new FooManager(); 

    private FooTemplate fooTemplate; 

    private FooManager() {  
     this.fooTemplate = new FooTemplate("ABC inc.", "93746789"); 
    } 

    public static FooManager getInstance() { 
     return fooManager; 
    } 

    public FooTemplate getFoo() { 
     return fooTemplate; 
    } 

} 

これはテスト・クラスがある:

public class FooTemplate { 

    private final String companyName; 

    private final String identifier; 

    private final List<String> serviceCenters = new ArrayList<String>(); 

    public FooTemplate(String companyName, String identifier) { 
     this.companyName = companyName; 
     this.identifier = identifier; 
    } 

    public String getCompanyName() { 
     return companyName; 
    } 

    public String getIdentifier() { 
     return identifier; 
    } 

    public List<String> getServiceCenters() { 
     return serviceCenters; 
    } 

    @Override 
    public String toString() { 
     return "FooTemplate [companyName=" + companyName + ", identifier=" 
       + identifier + ", serviceCenters=" + serviceCenters + "]"; 
    }  

} 

FooManagerはFooTemplateオブジェクトをロードシングルトンであります= ABC社、識別子= 93746789、serviceCenters = [シアトル、ボストン]]

FooTemplate【のcompanyName = ABC、INC。、識別子= 93746789、serviceCenters = [シアトル、ボストン、シアトル、ボストン]

FooTemplate【のcompanyName = ABC、INC。、識別子= 93746789、serviceCenters = [シアトル、ボストン、シアトル、ボストン、シアトル、ボストン]]

は、私は、同じオブジェクトが各反復で修正されているので、これが起こっていることを理解しています。オブジェクトを変更してコピーを返す前にオブジェクトを完全にコピーする必要がありますか、それともより良い解決策がありますか?

EDIT: 実際のコードでは、テンプレートオブジェクトはxmlを解析することによって作成され、解析はシングルトンで1回だけ行われます。これは、私が必要とするたびに新しいテンプレートオブジェクトを作成することができない理由です。

答えて

0

getFooに電話するたびにFooTemplateという新しいインスタンスを作成することができます。

public static FooTemplate getFoo() { 
    return new FooTemplate("ABC inc.", "93746789"); 
} 

それとも、あまりにも多くを作成したくない場合はcompanyNameidentifierString.intern()を呼び出すことを検討してください。 (私は、コンパイラはとにかくメモリ割り当てを最適化すると思います。)

2つの文字列がプログラム全体を通して、定数である場合は、static finalとして、それらを宣言することを検討してください。

一般的に、あなたがちょうどゼロからそれらを作成することができますしながら、別のオブジェクトをコピーすることをお勧めではありません。

編集: 新しいクラスFooCompanyを作成してください。

public class FooCompany { 

    private final String companyName; 

    private final String identifier; 

    public FooCompany(String companyName, String identifier) { 
     this.companyName = companyName; 
     this.identifier = identifier; 
    } 

    public String getCompanyName() { 
     return companyName; 
    } 

    public String getIdentifier() { 
     return identifier; 
    } 
} 


public class FooManager { 

    private static final FooManager fooManager = new FooManager(); 

    private FooCompany fooCompany; 

    private FooManager() {  
     this.fooCompany = new FooCompany("ABC inc.", "93746789"); 
    } 

    public static FooManager getInstance() { 
     return fooManager; 
    } 

    public FooTemplate getFoo() { 
     return new FooTemplate(fooCompany.getCompanyName(), fooCompany.getIdentifier()); 
    } 

} 
+0

上記の私の編集を参照してください以下でFooMangerを置き換えることができます。テンプレートオブジェクトは作成するのに費用がかかります。さまざまなテンプレートがあり、それらは一度作成され、アプリケーション全体で共有されます。 – booleano

+0

それはなぜ 'FooManager'のシングルトンですか? 'FooManager'のインスタンスがたくさんあることを意味しますか? – Dabiuteef

+0

いいえ、FooManagerはシングルトンです。テンプレートオブジェクトを初期化します。 – booleano

0

//あなたは、コード

パブリッククラスFooManager {

private static final FooManager fooManager = new FooManager(); 
//if company and contact are fix, make them final 
private final String COMPANY="ABC inc."; 
private final String CONTACT="93746789"; 

private FooManager() {  

} 

public static FooManager getInstance() { 
    return fooManager; 
} 

public FooTemplate getFoo() { 
    return new FooTemplate(COMPANY, CONTACT); 
} 

}

関連する問題