2016-11-19 7 views
1

ファイルから読み込み、自分の作成したコレクションクラスに情報を格納するプログラムを作成しました。私のプログラムはうまく動作しますが、私のプログラムを改善し、継承やその他のJava機能を使ってコードが重複しないようにするためにできることがあれば、私は疑問に思っていました。ここに私のクラスがあります。それぞれのクラスが何をしているのかを説明するコメントを追加しました。継承によるプログラムの改善

abstract class Order { //superclass 
private int quantity; //instance variables 

public Order(int quantity) { //constructor 
    this.quantity = quantity; 
} 

public int getQuantity() { // instance method 
    return quantity; 
} 

public abstract double totalPrice(); 

public String toString() { 
    return "quantity: " + quantity; 
} 

} //super Class Order 

class Coffee extends Order { //subclass 
private String size; //instance variables 

public Coffee (int quantity, String size) { //constructor 
    super(quantity); 
    this.size = size; 
} 

public double totalPrice() { //instance method to calculate price for the item 
    double priceSmall = 1.39; 
    double priceMed = 1.69; 
    double priceLar = 1.99; 
    double total = 0; 

    if (size.equals("small")) { 
    total = priceSmall * getQuantity(); 
    } else { 
    if (size.equals("medium")) { 
    total = priceMed * getQuantity(); 
    } else { 
    if(size.equals("large")) { 
     total = priceLar * getQuantity(); 
    } 
    } 
} 
    return total; 
} //totalPrice 


public String toString() { 
return "Coffee ("+ size + "): " + super.toString() ; 
} 

} //coffee sub-class 

class Donuts extends Order { //sub-class 
private double price; //instance variables 
private String flavour; 

public Donuts(int quantity, double price, String flavour) { //constructor 
super(quantity); 
this.price = price; 
this.flavour = flavour; 
} 


public double totalPrice() { //instance method to calculate price 
double total = 0; 
int quantity = getQuantity(); 

if(quantity < 6) { 
    total = (price * quantity); 
    double tax = 0.07 * total; 
    total += tax; 
} else { 
    total = price * quantity; 
} 
return total; 
} //totalPrice 

public String toString() { 
return "Donuts("+ flavour + "): " + super.toString() + ", price: " + price; 
} 

} //class Donuts 

class Sandwich extends Order { //Sub-class 
    private double price; // instance variables 
    private String filling; 
    private String bread; 

// constructor 
    public Sandwich (int quantity, double price, String filling, String bread) { 
    super(quantity); 
    this.price = price; 
    this.filling = filling; 
    this.bread = bread; 
} 

    public double totalPrice() { //instance method 
    double total = 0; 
    int quantity = getQuantity(); 

    total = (price * quantity); 
    double tax = 0.07 * total; 
    total += tax; 

    return total; 
    } //totalPrice 


    public String toString() { 
    return "Sandwich ("+ filling + ") (" + bread + "): "+ super.toString() + 
    ", price: " + price ; 
} 

} // Sandwich class 

    class Pop extends Order { //sub-class 
    private String size; 
    private String brand; 

    public Pop(int quantity, String size, String brand) { //constructor 
    super(quantity); 
    this.size = size; 
    this.brand = brand; 
    } 

    public double totalPrice() { //instance method 
    double priceSmall = 1.79; 
    double priceMed = 2.09; 
    double priceLar = 2.49; 
    double total = 0; 

    if (size.equals("small")) { 
    total = priceSmall * getQuantity(); 
} else { 
    if (size.equals("medium")) { 
    total = priceMed * getQuantity(); 
    } else { 
    if(size.equals("large")) { 
     total = priceLar * getQuantity(); 
    } 
    } 
} 
return total; 
} //totalPrice 

public String toString() { 
    return "Pop ("+ brand + ") (" + size + "): " + super.toString() ; 
} 
} // class Pop 

4つの製品を持つ受注私は保存して、その合計金額を印刷していますつまりコーヒー、ドーナツ、サンドイッチやポップがあります。

コーヒー、3、メディア

ドーナツ、7,0.89、チョコレート

ポップ、5、大、スプラット:

私が読んでいるファイルのサンプルはこれです!コーラ

サンドイッチ、1,3.89、謎の肉、37粒全粒小麦は

私のプログラムは少し長いですが、SOコミュニティは、私は私のプログラムの改善に役立つことができれば、私は期待しています。私が改善しようとしているのは、私はtotalPrice()というメソッドを各クラスでオーバーライドしているということです。しかし、あなたがよく見ると、coffeeクラスとpopクラスは、その属性が多少似ています。 donutクラスとsandwichesクラスも同じです。これらのクラスでコードの重複を防ぐことができますか? 説明が必要な場合は、私はすべてを自明に説明したいと思います。私はそれを提供したいと思います。

答えて

2

OOシステムで継承が過度に使用されることがあります。一般的に構成はより良いテクニックです - "継承対構成"を読み上げてください。

このケースでは、店舗の在庫アイテムを注文として扱うことは奇妙でおそらく役に立たないかもしれません。注文にはアイテムが関連付けられていますが、アイテムは実際には注文ではありません。

あなたは名前と価格を持つクラスStoreItemを持つことができます。また、クラスに価格に影響を与えるオプションのサイズプロパティを持たせることもできます。したがって、ストアアイテムの場合、item.getName()およびitem.getPrice()を呼び出すことができます。ストアアイテムを作成するときには、名前と価格だけで初期化するか、サイズを持つアイテムの名前、サイズ、価格で初期化することができます。

次に、Storeクラスを作成するだけで、ストアにはアイテムの一覧 - 利用可能なアイテムのリストがあります。品目の一覧が注文され、原価計算が指図クラスで一度発生する可能性があります。商品のリストをループして価格を尋ねるだけです。

このソリューションでは、Item、Store、Order、およびメインプログラムがどこかに終わりますが、新しいクラスを追加する必要のないアイテムを追加するように問題を拡張します。

+0

答えで判断すると、私は重大なコードの重複がないことを暗示していますか?私は 'StoreItem'クラスについてあなたが言っていることを得ました。 – Saad

+0

重複は、拡張性の問題ではありません。ソリューションにアイテムを追加するには、クラスを追加する必要があります。しかし、このソリューションでは、サイズが価格にどのように影響するかについて重複していますが、これは単一のStoreItemクラスを持つだけでは解消できます。 –

0

あなたのプログラムも問題ありませんが、仕様に基づいて質問に複数の解決策があります。

あなたが指定した最初のことは、重複を避けたいと思っていました。特に、いくつかの変更を加えなければならない場合は、totalPrice()メソッドで重複が発生します。たとえば、合計金額に1%割引を追加するような変更があります。これを考えると、私は以下のように変更を提案:

//add utility interface which can be used by all Concrete product classes 
interface PriceCalculator { 

    static double totalPrice(Map<String, Double> priceMap,String size, int quantity) throws Exception{ 
     Double rate=priceMap.get(size); 
     if(rate==null){ 
      throw new Exception("something really bad happened.Missing price"); 
     } 

     return (rate * quantity); 
    } 

} 

class Coffee extends Order { //subclass 
    private String size; //instance variables 
    private Map<String, Double> priceMap=new HashMap<>(); 

    public Coffee (int quantity, String size) { //constructor 
     super(quantity); 
     this.size = size; 
     priceMap.put("priceSmall", 1.39); 
     priceMap.put("priceMed", 1.69); 
     priceMap.put("priceLar", 1.39); 
    } 

    @Override 
    public double totalPrice() { //instance method to calculate price for the item 
     try { 
      return PriceCalculator.totalPrice(priceMap, size, getQuantity()); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      return 0; 
     } 
    } //totalPrice 


    public String toString() { 
     return "Coffee ("+ size + "): " + super.toString() ; 
    } 

} //coffee sub-class 

尋ねた場合は、別の仕様では、価格設定が難しいcoded.Youは、外部ファイルからサイズ・価格のキーと値のペアをロードするために、プロパティのクラスを使用していることを行うことができないようにすることです。