策略模式(行为型)
在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。
一、策略模式介绍
意图:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。
主要解决:在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护。
何时使用:一个系统有许多许多类,而区分它们的只是他们直接的行为。
如何解决:将这些算法封装成一个一个的类,任意地替换。
关键代码:实现同一个接口。
1、业务场景:每个订单,可选用一张优惠券
策略模式 ---------通过选择策略类,来执行不同算法分支。核心是通过注入对象,改变行为。此模式其实就是spring IOC思想。
2、时序图:
二、测试代码:
1、创建公用接口:
/**
* 定义公用的接口
*/
public interface Discount {
public int calculate(int money);
}
2、 满减策略方式:
/**
* 满减
*/
public class FullDiscount implements Discount {
@Override
public int calculate(int money) {
if (money > 200){
System.out.println("优惠减免20元");
return money - 20;
}
return money;
}
}
3、新客户优惠策略:
/**
* 首次购
*/
public class NewerDiscount implements Discount {
@Override
public int calculate(int money) {
if (money > 100){
return money - 20;
}
return money;
}
}
4、下单过程:
/**
* 模板方法模式
* 购物车费用结算过程
*/
public abstract class ShoppingCart {
private Discount discount;
private List<Fruit> products = new ArrayList<>();
public ShoppingCart(List<Fruit> products){
this.products = products;
}
public void setDiscount(Discount discount) {
this.discount = discount;
}
//提交订单主流程
public void submitOrder(){
//计算商品金额
int money = balance();
System.out.println("商品总金额为:"+money+"元");
//优惠减免
money = discount.calculate(money);
System.out.println("优惠减免后:"+ money+"元,");
//保存订单
pay(money);
//送货上门
sendHome();
}
//计算金额
private int balance(){
int money = 0;
System.out.print("商品清单:");
for (Fruit fruit : products){
fruit.draw();
System.out.print(",");
money += fruit.price();
}
return money;
}
private void sendHome(){
System.out.println("三公里以内,免费送货上门");
}
//提交保存
protected abstract void pay(int money);
}
5、客户端测试:
/**
* 策略模式
* 订单费用结算过程
*/
public class ShoppingCartClient {
private static Map<String,Discount> disCounts = new HashMap();
static {
/**
* 不同的优惠方案,类似spring容器初始化:策略模式
*/
disCounts.put("full",new FullDiscount());
disCounts.put("newer",new NewerDiscount());
disCounts.put("second",new SecondDiscount());
}
public static void main(String[] args) {
List<Fruit> products = new ArrayList();
products.add(StaticFactory.getFruitApple());
products.add(StaticFactory.getFruitBanana());
products.add(StaticFactory.getFruitOrange());
ShoppingCart cart = new OtherPayShopping(products);
//spring注入优惠方案,可以替代:策略模式
String discount = "second";
cart.setDiscount(disCounts.get(discount));
cart.submitOrder();
}
}
6、执行结果:
三、此模式在spring项目中的实战点睛:
1、根据不同参数动态获取不同的业务类(类似不同的优惠方案);
/**
* @author wanghuainan
* @date 2020/12/10 15:24
*/
@Component
public class BeanHelper implements ApplicationContextAware {
private static ApplicationContext applicationContext;
public static <T> T getBeanClass(Class<T> clazz){
if(Objects.isNull(applicationContext)){
throw new NullPointerException("Spring容器上下文未初始化");
}
return applicationContext.getBean(clazz);
}
// Object getBean(String var1) throws BeansException;
public static Object getServiceBeanClass(String serviceType){
if(Objects.isNull(applicationContext)){
throw new NullPointerException("Spring容器上下文未初始化");
}
return applicationContext.getBean(serviceType);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
2、server业务代码使用:
@Override
public int deleteUser(User user) {
//通过spring容器传不同的参数,获取到不同的业务类
UserService userService = (UserService )
BeanHelper.getServiceBeanClass(cableRelationModel.getRelationType());
//然后执行不同的业务
return userService .deleteUserInfo(user);
}
3、看到这大家就会豁然开朗的!不明白可以留言!
到此策略设计模式分析完成,下篇分析责任链模式,敬请期待!