描述
策略模式(Strategy Pattern) 定义了一系列的算法
,并将每一个算法封装
起来,而且使它们可以相互替换
,让算法独立于使用它的客户而独立变化。
介绍
意图:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。
主要解决:在有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护。
何时使用:一个系统有许多许多类,而区分它们的只是他们直接的行为。
如何解决:将这些算法封装成一个一个的类,任意地替换。
关键代码:实现同一个接口。
应用实例: 1、诸葛亮的锦囊妙计,每一个锦囊就是一个策略。 2、旅行的出游方式,选择骑自行车、坐汽车,每一种旅行方式都是一个策略。3、针对不同消费者级别, 采取不同的打折优惠,每一种优惠方式都是一个策略。
业务场景
购物消费是当下生活必不可少的一部分,商家也是针对不同消费群体类型做出不同的打折优惠策略,例如:普通用户、VIP用户、SVIP用户。
- 普通用户(normal)不给予任何优惠;
- VIP用户给与9折;
- SVIP用户给与8折;
代码实现
普通代码实现
现在买了一个价值100元的玩具,针对不同的用户,实际支付价格如下输出结果所示:
public double sale(String type, double fee){
if ("normal".equals(type)){
return fee;
} else if ("vip".equals(type)){
return fee * 0.9;
} else {
return fee * 0.8;
}
}
public static void main(String[] args) {
SpringObserverTest sot = new SpringObserverTest();
System.out.println("普通用户:"+sot.sale("normal", 100));
System.out.println("vip用户:"+sot.sale("vip", 100));
System.out.println("svip用户:"+sot.sale("svip", 100));
}
结果输出:
普通用户:100.0
vip用户:90.0
svip用户:80.0
策略模式实现
首先定义一个interface将所需成员组合起来,代码如下:
public interface DiscountService {
public String type();
public double discount(double fee);
}
然后分别将不同的用户类型实现DiscountService,代码如下:
普通用户:
@Component
public class NormalService implements DiscountService {
@Override
public String type() {
return "normol";
}
@Override
public double discount(double fee) {
return fee*1.0;
}
}
vip用户:
@Component
public class VipService implements DiscountService {
@Override
public String type() {
return "vip";
}
@Override
public double discount(double fee) {
return fee*0.9;
}
}
svip用户:
@Component
public class SvipService implements DiscountService {
@Override
public String type() {
return "svip";
}
@Override
public double discount(double fee) {
return fee*0.8;
}
}
调用入口:
@Service
public class SaleService {
HashMap<String, DiscountService> serviceHashMap = new HashMap<>();
//将所有的用户类型存储起来
public SaleService(List<DiscountService> discountServices) {
for (DiscountService discountService : discountServices){
serviceHashMap.put(discountService.type(), discountService);
}
}
//获取相对应的优惠
public double sale(String type, double fee){
return serviceHashMap.get(type).discount(fee);
}
}
结果输出:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = DemoApplication.class)
public class SpringObserverTest {
@Autowired
SaleService saleService;
@Test
public void test() {
double fee = saleService.sale("normol", 100);
System.out.println("nomal当前金额:"+fee);
fee = saleService.sale("vip", 100);
System.out.println("vip当前金额:"+fee);
fee = saleService.sale("svip", 100);
System.out.println("svip当前金额:"+fee);
}
}
控制台打印:
nomal当前金额:100.0
vip当前金额:90.0
svip当前金额:80.0
总结
策略模式(Strategy Pattern) 能够动态改变对象的行为,是通过 Context 本身的决策来改变组合的 Strategy 对象。所谓的状态转移,是指 sale 在运行过程中由于一些条件发生改变而使得 State 对象发生改变,注意必须要是在运行过程中。
策略模式(Strategy Pattern) 主要是用来封装一组可以互相替代的算法族,并且可以根据需要动态地去替换 sale 使用的算法。