2017-09-19 8 views
1

생성 된 클래스의 모든 인스턴스를 저장하는 정적 arraylist를 가진 Coin 클래스를 만들고 있는데, 초기 인스턴스로 그 목록을 초기화해야합니다. 어떻게해야하는지 알지 못했습니다. 중복 된 코드로 인해 두 번 추가하지 않고 할 수 있습니다. 제안 사항은 무엇입니까?초기 값을 가진 클래스의 인스턴스를 가진 정적 arraylist

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

* 정적 ArrayList에 *가 아니라이 패턴이 있음을 유의하시기 바랍니다 – Ravi

+2

을하려고 무엇인지 본질적으로 스레드 안전하지 않은 (즉, 기본적으로 thread-safe 코드를 만들 수는 없습니다.), 그렇게하는 것은 나쁜 습관입니다. 보다 나은 접근법은 사적 생성자와 그 생성자를 호출하고 그 인스턴스를'coins'에 추가하는 정적 팩토리 메소드입니다. – yshavit

+0

Coin 인스턴스를 생성 (및 반환)하는 CoinFactory 클래스를 만들어 자신에게 추가하는 것이 더 낫습니다. 현재 솔루션은 스레드로부터 안전하지 않으며 단지 단점 일뿐입니다. – DodgyCodeException

답변

0

모범 사례 패턴을 사용하여 응용 프로그램을 디자인 할 수도 있습니다. 당신은 모든 생성 된 동전의 등록을 유지하기를 원합니다. 이것은 Coin 클래스 자체의 외부에 보관하는 것이 가장 좋습니다. 당신은 동전 생성을 관리하고 그것을 만든 목록을 유지하는 수업을 가질 수 있습니다. Coin 클래스 자체는 인터페이스가 될 수 있습니다. 원하는 경우 CoinFactory가 아닌 인터페이스를 만들 수 있습니다.

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

당신은 전혀 변경할 정적 변수를 가지고 주장하는 경우 - 그것은 일반적으로 전혀 이런 일을 할 수있는 좋은 생각이 아니다 - 당신이 추가

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

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

을 ... 할 수 요소를 즉시 목록에 추가하십시오.

+0

더 나은 아이디어는 무엇입니까? –

+3

당신이 만드는 모든 동전을 저장하는 실제 수업을 가지십시오. 생성자에 연결하지 않고 명시 적으로 모두 나열하십시오. –

+0

맞아, 고마워! –

1

선언에서 목록을 초기화하고 각 인스턴스를 생성자의 목록에 추가하는 것을 중단하게되는 이유는 무엇입니까?

+2

그것이 OP가하는 일입니다.하지만 원하는 것은이 클래스의 사용자가 수동으로 인스턴스를 생성하지 않고도 하나의 Coin ("Pesos chilenos")이 "자동으로"추가되는 것입니다. – yshavit