Design patterns 如何着手解决这个问题(设计模式)
我有一个计费系统,不同类型的客户有不同类型的折扣方案。对于给定的票据,应根据客户和产品的类型生成应付净额 而且也没有什么规则。比如: •如果用户是商店的员工,他可以获得30%的折扣 •如果用户是该商店的附属机构,则可获得10%的折扣 •如果用户已成为客户超过2年,则可获得5%的折扣 •账单上每100美元,将有5美元的折扣(例如,对于990美元,您将获得45美元的折扣) •基于百分比的折扣不适用于食品杂货 我脑子里几乎没有什么想法。第一个赌注是考虑装饰图案:Design patterns 如何着手解决这个问题(设计模式),design-patterns,Design Patterns,我有一个计费系统,不同类型的客户有不同类型的折扣方案。对于给定的票据,应根据客户和产品的类型生成应付净额 而且也没有什么规则。比如: •如果用户是商店的员工,他可以获得30%的折扣 •如果用户是该商店的附属机构,则可获得10%的折扣 •如果用户已成为客户超过2年,则可获得5%的折扣 •账单上每100美元,将有5美元的折扣(例如,对于990美元,您将获得45美元的折扣) •基于百分比的折扣不适用于食品杂货 我脑子里几乎没有什么想法。第一个赌注是考虑装饰图案: Customer <<I
Customer <<Interface>>
|
CustomerImpl
DiscountDecorator <<AbstractClass>> imp Customer
| | | |
AffiDiscount StoreEmp OverTwoYears AnyOtherDisc
Discount Discount Discount
Items {
//? ? :/
}
客户
|
客户模板
折扣装饰器imp客户
| | | |
在任何其他光盘上粘贴折扣商店EMP超过两年
折扣
项目{
//? ? :/
}
但是折扣
也取决于项目
我有什么选择
- 使用
界面扩展项目
界面以跟踪项目类型客户
- 将
项目的
传递给折扣类。 ... 如何正确地与列表
和客户
类建立关系,以便我可以一起装饰它们项目
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);
}
}
我还不认为需要一种模式,也许可以这样做:
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("---");
}
}
import java.util.EnumSet;
公共类So35680415{
枚举折扣{
雇员{
@覆盖双倍折扣(双倍金额){
退货金额*.30;
};
},
附属公司{
@覆盖双倍折扣(双倍金额){
//TODO自动生成的方法存根
退货金额*.10;
};
},
顾客两年{
@覆盖双倍折扣(双倍金额){
返回数学下限(金额/100)*100*.05;
};
};
双倍折扣(双倍金额);
}
静态类用户{
无效折扣(双倍金额){
对于(折扣:折扣)
System.out.println(“折扣:“+折扣+”在:$”+金额+“是:$”+折扣.折扣(金额));
}
EnumSet折扣=EnumSet.noneOf(折扣.class);
}
公共静态void main(字符串[]args){
用户=新用户();
用户.折扣.添加(折扣.员工);
用户折扣(100);
System.out.println(“--”);
用户.折扣.添加(折扣.附属);
用户折扣(100);
System.out.println(“--”);
user.discounts.add(Discount.customerfortwyears);
用户折扣(100);
System.out.println(“--”);
}
}
编辑以回答问题:它似乎没有违反srp,因为它只做了一件事,即计算折扣。枚举似乎非常适合此任务。枚举的类型是子类。添加另一个枚举很容易。它看起来确实有点像@Downvoter请说明你的否决理由,这样问题就可以得到改进。为什么
Employee
类也必须实现Customer
?它没有实现(至少在给出此示例的Java中没有实现),但如果接口继承不太麻烦的话,我喜欢对它进行明确的说明?2) 是否应为枚举分配此类任务?枚举中的类型不是有资格成为子类吗?如果将来会增加折扣呢?
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("---");
}
}