2017-09-19 18 views
1

作成したクラスのすべてのインスタンスを格納する静的arraylistを持つCoinクラスを作成していますが、初期インスタンスでそのリストを開始する必要がありますそれは2回追加することなく(冗長コードのために)、何か提案しますか?追加あなたが初期値を持つクラスのインスタンスを持つ静的arraylist

private static ArrayList<Coin> coins = 
     new ArrayList<>(); 

static { 
    new Coin("Pesos chilenos", "CLP", 1f, "CLP"); 
} 

を行うことができ... -

public class Coin { 
    private static ArrayList<String> coinNames = new ArrayList<>(); 
    private static ArrayList<String> coinAbbreviations = new ArrayList<>(Arrays.asList("CLP")); 
    private static ArrayList<Coin> coins = 
      new ArrayList<>(Arrays.asList(new Coin("Pesos chilenos", "CLP", 1f, "CLP"))); 
    private static HashMap<String,Float> exchangeRates; 
    private String coinName; 
    private String coinAbbreviation; 
    private Float coinValue; 
    private String unit; 


    public Coin(String coinName, String coinAbbreviation, Float coinValue, String unit) { 
     assert !coinAbbreviations.contains(coinAbbreviation) : "Coin abbreviation already used"; 
     assert coinAbbreviations.contains(unit) : "Coin unit non existent."; 
     assert !coinNames.contains(coinName) : "Coin name already used."; 
     this.coinName = coinName; 
     this.coinAbbreviation = coinAbbreviation; 
     this.coinValue = coinValue; 
     this.unit = unit; 

     coins.add(this); 
    } 
} 
+1

あなたが – Ravi

+2

をやろうとしているかわからない*すべてのインスタンスを格納*静的ArrayListのこと(このパターンは本質的にスレッド安全ではないことに注意してください。基本的にはスレッドセーフなコードを作ることはできません)、悪い習慣です。より良いアプローチは、プライベートコンストラクタと、そのコンストラクタを呼び出してインスタンスを 'coins'に追加する静的ファクトリメソッドです。 – yshavit

+0

Coinインスタンスを作成して返すCoinFactoryクラスを用意して、それを自分自身に追加する方がよいでしょう。現在のソリューションはスレッドセーフではなく、それは単なる1つの欠点です。 – DodgyCodeException

答えて

0

また、いくつかのベストプラクティスパターンを使用してアプリケーションを設計することもできます。あなたはすべての作成されたコインのレジストリを保持したい。これは、Coinクラスそのものの外部に置かれるのが最善です。コインの作成を管理し、作成したコインのリストを保持するクラスを持つことができます。 CoinFactory以外では作成できないように、Coinクラス自体をインターフェイスとして使用できます。

public interface Coin { 
    String name(); 
    String abbreviation(); 
    BigDecimal value(); 
    String unit(); 
} 

コインファクトリクラス:

public class CoinFactory { 

    // Concrete coin is an internal implementation class whose details don't 
    // need to be known outside of the CoinFactory class. 
    // Users just see it as interface Coin. 
    private static class ConcreteCoin implements Coin { 
     private final String name; 
     private final String abbreviation; 
     private final BigDecimal value; 
     private final String unit; 

     ConcreteCoin(String name, String abbreviation, BigDecimal value, String unit) { 
      this.abbreviation = abbreviation; 
      this.name = name; 
      this.value = value; 
      this.unit = unit; 
     } 

     public String name() { return name; } 
     public String abbreviation() { return abbreviation; } 
     public BigDecimal value() { return value; } 
     public String unit() { return unit; } 
    } 

    // Sets for enforcing uniqueness of names and abbreviations 
    private Set<String> names = new HashSet<>(); 
    private Set<String> abbreviations = new HashSet<>(); 

    // All coins must have one of the following ISO currency codes as the 'unit' field. 
    private final Set<String> allIsoCurrencyCodes = 
      Set.of("CLP", "GBP", "EUR", "CAD", "USD", "XXX" /* , ... */); 

    private List<Coin> allCoins = new ArrayList<>(
      List.of(createCoin("Pesos chilenos", "CLP", BigDecimal.ONE, "CLP"))); 

    private List<Coin> unmodifiableListOfAllCoins = 
      Collections.unmodifiableList(allCoins); 


    public Coin createCoin(String name, String abbreviation, BigDecimal value, String unit) { 
     if (!names.add(name)) 
      throw new IllegalArgumentException("Name already exists: " + name); 
     if (!abbreviations.add(abbreviation)) 
      throw new IllegalArgumentException("Abbreviation already exists: " + abbreviation); 
     if (!allIsoCurrencyCodes.contains(unit)) 
      throw new IllegalArgumentException("Coin unit is not a recognised ISO currency code: " + unit); 

     Coin coin = new ConcreteCoin(name, abbreviation, value, unit); 
     allCoins.add(coin); 
     return coin; 
    } 

    public Collection<Coin> allCoins() { 
     return unmodifiableListOfAllCoins; 
    } 
} 
5

あなたがすべてで変更可能な静的変数を持つことを主張した場合 - それがすべてで、このようなことを行うには、一般的には良い考えではありません要素をすぐにリストに追加します。

+0

次に良いアイデアは何ですか? –

+3

あなたが作るすべての硬貨を保管する実際のクラスがあります。それをコンストラクタに結び付けてはいけません。すべて明示的にリストしてください。 –

+0

右、ありがとう! –

1

宣言でリストを初期化してから、各インスタンスをコンストラクタのリストに追加するだけでは何が止まりますか?

+2

これはOPがやっていることですが、彼らが望むのは、このクラスのユーザーが手作業でインスタンス化しなくても、1つのCoin( "Pesos chilenos")が自動的に追加されることです。 – yshavit

関連する問題