需求
针对店下商铺,有这样一个需求,对用户客户分为了普通客户、vip
客户、超级vip
用户、专属vip
用户4
个等级,每当用户购买商品时,针对不同的用户等级和消费金额采取不同的打折优惠策略。在平常的开发当中,必然会出现多层的if-else
嵌套判断,先判断用户的等级再判断用户购买商品的消费金额。
弊端
以上的情况出现了多层的if-else
嵌套,除此之外,以后如果需求再有变动,需要再增加一个用户等级,那么又会再次添加if-else
的嵌套判断,那么如何解决上述的弊端呢,采用策略模式和工厂模式的搭配使用,可以很好地优化多层if-else
的多层嵌套
实现
编写用户等级枚举类
package com.zbiti.ifelse.UserType; /** * 用户类型枚举类 */ public enum UserPayServiceEnum { VIP(1,"Vip"), SUPERVIP(2,"SuperVip"), PARTICULALYVIP(3,"ParticularlyVip"), NORMAL(4,"NormalPayService"); /** * 状态值 */ private int code; /** * 类型描述 */ private String value; private UserPayServiceEnum(int code, String value) { this.code = code; this.value = value; } public int getCode() { return code; } public String getValue() { return value; } public static UserPayServiceEnum valueOf(int code) { for (UserPayServiceEnum type : UserPayServiceEnum.values()) { if (type.getCode()==code) { return type; } } return null; } public static void main(String[] args) { System.out.println(UserPayServiceEnum.VIP.getValue()); } }
编写不同的用户等级策略类
以下需要注意的是每个策略类实现了InitializingBean
接口的作用是每当策略类被spring
容器启动初始化后会调用afterPropertiesSet
方法,而在这个方法里面的作用是会往工厂里针对不同用户等级保存其对应的用户策略引用
编写打折接口
不同的用户等级策略类实现该接口,该接口包含了打折方法
package com.zbiti.ifelse.UserType; import java.math.BigDecimal; public interface UserPayService { /** * 计算应付价格 */ public BigDecimal quote(BigDecimal orderPrice); }
编写普通用户策略类
package com.zbiti.ifelse.UserType; import org.springframework.beans.factory.InitializingBean; import org.springframework.stereotype.Service; import java.math.BigDecimal; /** * 普通会员不打折原价 */ //实现InitializingBean接口,容器启动后会调用afterPropertiesSet()方法,往工厂里写入打折策略 @Service public class NormalPayService implements UserPayService, InitializingBean { @Override public BigDecimal quote(BigDecimal orderPrice) { return new BigDecimal("10"); } @Override public void afterPropertiesSet() throws Exception { UserPayServiceStrategyFactory.register(UserPayServiceEnum.NORMAL.getValue(), this); } }
编写vip用户策略类
package com.zbiti.ifelse.UserType; import org.springframework.beans.factory.InitializingBean; import org.springframework.stereotype.Service; import java.math.BigDecimal; /** * 普通会员打9折,消费超100打8折 */ //实现InitializingBean接口,容器启动后会调用afterPropertiesSet()方法,往工厂里写入打折策略 @Service public class VipPayService implements UserPayService, InitializingBean { @Override public BigDecimal quote(BigDecimal orderPrice) { if (orderPrice.compareTo(new BigDecimal("100")) > 1) { return new BigDecimal("8"); } return new BigDecimal("9"); } public void myShow(){ System.out.println("myShow method invoke----->"); } @Override public void afterPropertiesSet() throws Exception { UserPayServiceStrategyFactory.register(UserPayServiceEnum.VIP.getValue(), this); } }
编写超级vip用户策略类
package com.zbiti.ifelse.UserType; import org.springframework.beans.factory.InitializingBean; import org.springframework.stereotype.Service; import java.math.BigDecimal; /** * 超级会员打8折 */ @Service public class SuperVipPayService implements UserPayService , InitializingBean { @Override public BigDecimal quote(BigDecimal orderPrice) { return new BigDecimal("8"); } @Override public void afterPropertiesSet() throws Exception { UserPayServiceStrategyFactory.register(UserPayServiceEnum.SUPERVIP.getValue(),this); } }
编写专属用户vip策略类
package com.zbiti.ifelse.UserType; import org.springframework.beans.factory.InitializingBean; import org.springframework.stereotype.Service; import java.math.BigDecimal; /** * 专属会员 下单消费超30打七折 */ @Service public class ParticularlyVipPayService implements UserPayService, InitializingBean { @Override public BigDecimal quote(BigDecimal orderPrice) { if (orderPrice.compareTo(new BigDecimal("30"))>0) { return new BigDecimal("7"); } return new BigDecimal("8"); } @Override public void afterPropertiesSet() throws Exception { UserPayServiceStrategyFactory.register(UserPayServiceEnum.PARTICULALYVIP.getValue(),this); } }
编写工厂类
注意这里工厂的register
方法,该方法会在spring
容器启动初始化bean
即各个不同等级的用户策略类完成后调用afterPropertiesSet
方法里调用register
方法,当容器启动完成后,我们的spring
容器中即有了一个键为用户等级,值为用户等级策略类的map
,在对不同用户进行优惠打折的时候,可以根据用户等级来取得当前用户的策略类
package com.zbiti.ifelse.UserType; import org.springframework.util.Assert; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * 版本二:工厂使用(高级版) */ //@Service public class UserPayServiceStrategyFactory { private static Map<String,UserPayService> services = new ConcurrentHashMap<String,UserPayService>(); public static UserPayService getByUserType(String type){ return services.get(type); } public static void register(String userType,UserPayService userPayService){ Assert.notNull(userType,"userType can't be null"); services.put(userType,userPayService); } }
编写测试类
package com.zbiti.ifelse; import com.zbiti.ifelse.UserType.UserPayService; import com.zbiti.ifelse.UserType.UserPayServiceStrategyFactory; import com.zbiti.ifelse.UserType.VipPayService; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import java.math.BigDecimal; @SpringBootTest @Slf4j class IfElseApplicationTests { @Test void contextLoads() { calPrice(); } public void calPrice() { BigDecimal orderPrice = new BigDecimal("100"); String vipType = "Vip"; //指定用户类型,获得相对应的策略 UserPayService strategy = UserPayServiceStrategyFactory.getByUserType(vipType); // UserPayService strategy2 = UserPayServiceStrategyFactory2.getByUserType(vipType); System.out.println(strategy); // System.out.println(strategy2); BigDecimal quote = strategy.quote(orderPrice); if(strategy instanceof VipPayService){ ((VipPayService) strategy).myShow(); } System.out.println(quote); } }
结果
可以看到vip
用户打9
折,在这个不同用户等级购买商品时采取的不同打折策略里,我们没有出现了多层的if-else
的嵌套
转载:https://www.cnblogs.com/lisingshen/p/11782250.html