2016-02-28 69 views
-1

我有一個計費系統,其中不同類型的客戶有不同類型的折扣方案。對於給定的賬單,應根據客戶和產品的類型生成淨應付賬款金額。如何去解決這個問題(設計模式)

而且也有一些規則。像:

•如果用戶是店裏的員工,他得到30%的折扣

•如果用戶是店裏的會員,他得到10%的折扣

•如果該用戶已經超過2年的客戶,他得到了5%的折扣。

•賬單上每100美元就會有5美元的折扣(例如990美元,折扣爲45美元)。

•百分比折扣基礎上不雜貨 申請...

我在我的腦海裏有幾個想法。第一個辦法是考慮一個裝飾圖案:

Customer <<Interface>>  

|      
CustomerImpl 



DiscountDecorator <<AbstractClass>> imp Customer 

|    |   |   | 
AffiDiscount StoreEmp OverTwoYears AnyOtherDisc 
       Discount  Discount  Discount 
Items { 
//? ? :/ 
} 

但隨後Discounts取決於Items爲好。

我有什麼選擇?

  • extend Customer接口與Item接口跟蹤項目的類型?
  • 通過ListItems折扣類。 ... 如何正確地與CustomerItem類共同關聯,以便我可以將它們裝飾在一起?
+1

@Downvoter請說明你的反對理由,以便可以改善問題。 –

回答

0

我沒有看到需要的模式呢,也許只是做這樣的事情:

import java.util.EnumSet; 
public class So35680415 { 
    enum Discount { 
     employee { 
      @Override double discount(double amount) { 
       return amount*.30; 
      }; 
     }, 
     affiliate { 
      @Override double discount(double amount) { 
       // TODO Auto-generated method stub 
       return amount*.10; 
      }; 
     }, 
     customerForTwoYears { 
      @Override double discount(double amount) { 
       return Math.floor(amount/100)*100*.05; 
      }; 
     }; 
     abstract double discount(double amount); 
    } 
    static class User { 
     void discounts(double amount) { 
      for(Discount discount:discounts) 
       System.out.println("discount for: "+discount+" on: $"+amount+" is: $"+discount.discount(amount)); 
     } 
     EnumSet<Discount> discounts=EnumSet.noneOf(Discount.class); 
    } 
    public static void main(String[] args) { 
     User user=new User(); 
     user.discounts.add(Discount.employee); 
     user.discounts(100); 
     System.out.println("---"); 
     user.discounts.add(Discount.affiliate); 
     user.discounts(100); 
     System.out.println("---"); 
     user.discounts.add(Discount.customerForTwoYears); 
     user.discounts(100); 
     System.out.println("---"); 
    } 
} 

編輯回答問題:它似乎沒有違反srp,因爲它只做一件事情,即計算折扣。枚舉看起來是理想的任務。枚舉類型的子類。添加另一個枚舉很容易。它確實看起來像strategy pattern

+0

有幾個問題:1)它不違反SRP嗎? 2)Enum應該分配這樣的任務嗎? Enum中的類型是否有資格成爲子類?如果未來還有折扣的增加會怎麼樣? –

0

我不認爲你應該使用裝飾模式(除非有更多的這個問題,那麼我明白了)。簡單的多態可以做到這一點。

public abstract class AbstractCustomer implements Customer { 

    private List<Item> items = new ArrayList<Item>(); 

    protected abstract double priceDiscountedPercentage(Item item); 

    private double priceDiscounted(double bill) { 
     return (bill - (Math.floor(bill/100) * 5)); 
    } 

    public void addItem(Item item) { 
     items.add(item); 
    } 

    public double ringUp() { 
     double bill = 0; 
     for(Item item : items) { 
      if(!item.isGrocery()) { 
       bill += priceDiscountedPercentage(item); 
      } else { 
       bill += item.getPrice(); 
      } 
     } 
     return priceDiscounted(bill); 
    } 
} 

然後你就會有不同的客戶類別,例如:

public class Employee extends AbstractCustomer implements Customer { 
    @Override 
    protected double priceDiscountedPercentage(Item item) { 
     return (item.getPrice() * 0.7); 
    } 
} 
+0

爲什麼'Employee'類也必須實現'Customer'? –

+0

它沒有(至少不是在給出這個例子的Java中),但是如果它不太麻煩,我喜歡明確地說明接口繼承。 – Assaf