请看下面的例子:
一、请编写一个商城的收银系统,能应对商城不同的优惠变化
1.假设该商城有三种不同的优惠策略(没有折扣,打几折,满多少返现)
折扣策略抽象类:
public abstract class Sale {
private double price;
private int num;
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public abstract double getResult();
}
没有折扣子类:
public class SaleForNo extends Sale{
public SaleForNo(double price,int num) {
setNum(num);
setPrice(price);
}
@Override
public double getResult() {
return getPrice()*getNum();
}
}
打n折子类:
public class SaleForOff extends Sale{
private double offNum;
public double getOffNum() {
return offNum;
}
public void setOffNum(double offNum) {
this.offNum = offNum;
}
public SaleForOff(double price,int num,double offNum) {
setNum(num);
setPrice(price);
this.offNum=offNum;
}
@Override
public double getResult() {
return getPrice()*getNum()*offNum;
}
}
满多少返现:
public class SaleForReturn extends Sale{
private double standard;
private double returnMoney;
public double getStandard() {
return standard;
}
public void setStandard(double standard) {
this.standard = standard;
}
public double getReturnMoney() {
return returnMoney;
}
public void setReturnMoney(double returnMoney) {
this.returnMoney = returnMoney;
}
public SaleForReturn(double price,int num,double standard,double returnMoney) {
setNum(num);
setPrice(price);
this.returnMoney=returnMoney;
this.standard=standard;
}
@Override
public double getResult() {
double oriResult=getNum()*getPrice();
if(oriResult>=standard) {
return oriResult-Math.floor(oriResult/standard)*returnMoney;
}
return oriResult;
}
}
策略选择上下文类:
public class SaleContext {
private Sale sale;
public Sale getSale() {
return sale;
}
public void setSale(Sale sale) {
this.sale = sale;
}
public SaleContext(Sale sale) {
this.sale=sale;
}
public double getFinallyResult() {
return sale.getResult();
}
}
测试类:
public class Test {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
String flag=scanner.nextLine();
scanner.close();
Sale sale;
switch(flag) {
case "原价":
sale=new SaleForNo(100, 1);
break;
case "打7折":
sale=new SaleForOff(100, 1, 0.7);
break;
case "满100返现50":
sale=new SaleForReturn(100, 1, 100, 50);
break;
default:
throw new RuntimeException("不支持的折扣方式");
}
SaleContext sc=new SaleContext(sale);
System.out.println("折扣后:"+sc.getFinallyResult());
}
}
在这里可以注意到:简单工厂模式和策略模式非常的相似,不同的是简单工厂模式(创建型)针对的是对象的创建,而策略模式(行为型)针对的是对算法的替换、配置。(通俗的来说,策略模式客户端已经创建一个策略对象,然后关注拿着这个策略办的事;简单工厂模式需要自己根据客户端传入的标志创建对象,然后把对象返回 )
2.将策略模式和简单工厂模式相结合
即在context类中融入简单工厂模式:
public class SaleContext {
private Sale sale;
public Sale getSale() {
return sale;
}
public void setSale(Sale sale) {
this.sale = sale;
}
public SaleContext(String flag) {
switch(flag) {
case "原价":
sale=new SaleForNo(100, 1);
break;
case "打7折":
sale=new SaleForOff(100, 1, 0.7);
break;
case "满100返现50":
sale=new SaleForReturn(100, 1, 100, 50);
break;
default:
throw new RuntimeException("不支持的折扣方式");
}
}
public double getFinallyResult() {
return sale.getResult();
}
}
测试类:
public class Test {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
String flag=scanner.nextLine();
scanner.close();
SaleContext sc=new SaleContext(flag);
System.out.println("折扣后:"+sc.getFinallyResult());
}
}
能明显地看出算法类已经和测试类完全的解耦!