23中设计模式——策略模式
一、基本概念
定义:什么是策略模式?个人认为,策略模式就是对一种行为有不同的“动作”,根据用户的需求进行选择不同的“动作”。 ps:个人认为有点类似于多态。
例子:在商城的购物过程中,针对不同用户有着不同的折扣。譬如,普通用户原价,白银用户9折,黄金用户8折。针对不同的用户有着不同的折扣,这样就可以使用到策略模式。
二、实例运用
商场收银系统,根据商品的单价和数量算出总价格。但是遇到商场不同的活动,有时候会全场打折9折,8折。有时候会是满减活动,譬如全场满200减50之类的。
package com.golf.strategy;
/**
* 创建抽象类---策略模式
*/
abstract class Strategy {
public abstract double useAlgorithm(double money);
}
创建相应的具体算法实现,继承Strategy。通过构造方法,将需要的值写入。
打折收费:
package com.golf.strategy;
//打折收费
public class CashDiscount extends Strategy {
private double discount;
//每个具体的策略类的参数 都是自身特有的参数
public CashDiscount(double discount){
this.discount = discount;
}
@Override
public double useAlgorithm(double money) {
return money * discount;
}
}
正常收费:
package com.golf.strategy;
//正常收费
public class CashNomarl extends Strategy {
@Override
public double useAlgorithm(double money) {
return money;
}
}
折返收费:
package com.golf.strategy;
//满减收费 譬如满200-50
public class CashReturn extends Strategy{
private double condition;
private double returnMoney;
public CashReturn(double condition,double returnMoney){ //构造函数是每个具体的策略类的特有的参数
this.condition = condition;
this.returnMoney = returnMoney;
}
@Override
public double useAlgorithm(double money) { //重写抽象的策略类的参数都是共同的
return money-Math.floor(money/condition)*returnMoney;
}
}
上下文环境类----有点类似于简单工厂模式里面的工厂
package com.golf.strategy;
public class StrategyContext {
private Strategy strategy; //创建定义的抽象父类(接口)
public StrategyContext(Strategy strategy){ //通过构造函数进行
this.strategy = strategy;
}
public double exc(double money){
double result = strategy.useAlgorithm(money);
return result;
}
}
客户端:
package com.golf.strategy;
import java.util.Scanner;
//客户端的实现
public class Client {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
System.out.println("请输入单价:");
String singlePrice = input.next();
System.out.println("请输入商品数量:");
String num = input.next();
double money = Double.parseDouble(singlePrice)*Double.parseDouble(num); //总价
//根据自己所需要的算法 创建相应的对象
StrategyContext strategyContext = new StrategyContext(new CashDiscount(0.8));
double exc = strategyContext.exc(money);
System.out.println("总价为:"+exc);
}
}
其实可以将创建具体的那种策略放到Strategy类中,将简单工厂模式和策略类结合一下
上下文环境的StrategyContext
将策略模式和简单工厂模式结合之后,client避免直接去创建需要的对象,而是通过上下文环境类去创建。这样client只需要消费就行,减少了耦合度。
package com.golf.strategy;
public class StrategyContext2 {
private Strategy strategy;
public StrategyContext2(String type){
switch (type){
case "普通消费":
this.strategy = new CashNomarl();
break;
case "打折消费":
this.strategy = new CashDiscount(0.8);
break;
case "满减活动":
this.strategy = new CashReturn(200,100);
}
}
public double exc(double money){
double result = strategy.useAlgorithm(money);
return result;
}
}
客户端:
package com.golf.strategy;
import java.util.Scanner;
//将策略模式和简单工厂模式进行结合
public class Client2 {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
System.out.println("请输入单价:");
String singlePrice = input.next();
System.out.println("请输入商品数量:");
String num = input.next();
double money = Double.parseDouble(singlePrice)*Double.parseDouble(num); //总价
//根据自己所需要的算法 创建相应的对象
StrategyContext2 strategyContext = new StrategyContext2("满减活动");
double exc = strategyContext.exc(money);
System.out.println("总价为:"+exc);
}
}
三、策略模式的优缺点
优点:
1、算法可以自由的切换,根据用户的需求,使用不同的算法。
缺点:
1、每一个策略都是一个类,当项目的复杂度上升的时候,策略过多,类变多,复杂性大大上升。
package com.golf.strategy;
import java.util.Scanner;
//将策略模式和简单工厂模式进行结合
public class Client2 {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
System.out.println("请输入单价:");
String singlePrice = input.next();
System.out.println("请输入商品数量:");
String num = input.next();
double money = Double.parseDouble(singlePrice)*Double.parseDouble(num); //总价
//根据自己所需要的算法 创建相应的对象
StrategyContext2 strategyContext = new StrategyContext2("满减活动");
double exc = strategyContext.exc(money);
System.out.println("总价为:"+exc);
}
}