2016-11-19 3 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 

커피, 도넛, 샌드위치, 팝 주문이 있으며 총 주문 금액을 저장하고 인쇄하는 주문이 있습니다.

커피, 3, 매체

도넛, 7,0.89, 초콜릿

팝, 5, 대형 경고등 :

내가 읽고있다 파일의 샘플이 있습니다 ! 콜라

샌드위치, 1,3.89, 미스터리 고기, 37 곡물 전체 밀

내 프로그램은 약간 긴하지만, SO 커뮤니티 내 프로그램을 개선하는 데 도움이 할 수 있다면 내가 기대하고있다. 내가 개선하기 위해 찾고있는 것은, 내가 각 클래스에서 무시하고있는 totalPrice() 메서드가 있다는 것입니다. 그러나 당신이 가깝게 보면 coffee 클래스와 pop 클래스는 그 속성이 다소 비슷합니다. donut 클래스와 sandwiches 클래스도 동일합니다. 해당 클래스에서 코드의 중복을 막을 수있는 방법이 있습니까? 설명이 필요하다면 모든 것을 설명 할 수 있기를 바랍니다. 나는 그것을 기꺼이 제공 할 의향이 있습니다.

답변

2

OO 시스템에서 상속이 종종 지나치게 사용됩니다. 일반적으로 구성이 더 나은 기술입니다 - "상속 vs. 구성"을 읽어보십시오.

이 경우 특별히 상점의 재고 항목을 주문으로 취급하려고 시도하는 것이 이상하고 도움이되지 않을 수도 있습니다. 주문에는 항목이 있지만 주문 자체는 실제로 주문이 아닙니다.

그런 점에서 이름과 가격이있는 클래스 StoreItem을 사용할 수 있습니다. 또한 클래스에 가격에 영향을 미치는 선택적 크기 속성을 허용 할 수 있습니다. 따라서 상점 항목에 대해서는 item.getName() 및 item.getPrice()를 호출 할 수 있습니다. 스토어 아이템을 만들 때, 네임드와 가격만으로 초기화하거나 사이즈가있는 아이템의 이름, 크기, 가격으로 초기화 할 수 있습니다.

그런 다음 저장소 클래스 만 가질 수 있으며 저장소에는 항목 목록 - 사용 가능한 항목 목록이 있습니다. 품목 목록에 대한 주문이 이루어지고 주문 클래스에서 비용 계산이 한 번 발생할 수 있습니다. 그냥 항목 목록을 반복하고 각각의 가격을 묻습니다.

이 솔루션을 사용하면 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 외부 파일 크기 가격의 키 - 값 쌍을로드 속성 클래스를 사용하여 해당 작업을 수행 할 수 없습니다 수 있도록하는 것입니다.