目录
实际开发中的痛点
在实际的开发中,我们会经常和if else语句打交道,你是否早已痛恨冗长的代码判断,譬如以下代码
// param {userType} userType用户类型:1:普通用户 2:vip用户 3:svip用户
String txt = "";
if(userType== 1){
txt = "普通用户" ;
}else if(userType== 2){
txt = "vip用户" ;
}else if(userType== 3){
txt = "svip用户" ;
}
在实际的开发中,我们面对多用户处理相同动作的事第一会想到的一定会是使用if语句进行判断,但这样做往往会造成代码过长,代码冗余的现象,而且一旦其中一类用户进行更改,我们还得去再冗长的if判断中寻找需要更改的代码块,这样做很不方便, 同样的使用switch也会出现同类问题,那我们有什么办法来给代码解耦呢
策略模式的应用
我们知道,在Java的23中设计模式中,存在一种对象行为模式,可以将一组算法中的每一组算法单独封装到具有公共接口的类中,从而使得他们可以相互替换 ,没错,那就是策略模式,那么我们应该怎样进行实际应用呢,这里我们以在消费中不同用户类型获取不同折扣为例,给大家演示一下
首先我们建立不同用户的枚举 UserTypeEnum
/**
* 用户类型枚举
* @author hys
* @date 2022/8/9 10:35
*/
public enum UserTypeEnum {
//超级vip用户
SUPER_VIP,
//vip用户
VIP,
//普通用户
COMMON;
}
其次我们建立策略模式中提到的那个公共接口 UserTypeService 在接口中我们定义两个方法,一个是用于获取用户类型的 getUserType 方法和一个获取打折后价格的方法 getDiscountAmount
/**
* 用户类型
* @author hys
* @date 2022/8/9 10:34
*/
public interface UserTypeService {
/**
* 获取用户类型
* @return 用户类型枚举
*/
UserTypeEnum getUserType();
/**
* 获取折扣后金额
* @param amount 总金额
* @return 折扣后金额
*/
Double getDiscountAmount(Double amount);
}
做完这些之后,我们再编写一个中心处理类,用于注册UserTypeService的实现,创建用户中心 类CenterUserHandleService
/**
* 用户策略处理
* @author hys
* @date 2022/8/9 10:33
*/
@Service
public class CenterUserHandleService {
/**
* 也可使用hashmap代替
*/
private final EnumMap<UserTypeEnum,UserTypeService> userTypeServiceEnumMap = new EnumMap<>(UserTypeEnum.class);
/**
* 注册用户策略、构造方法会把{@link UserTypeService}所有的实现类注册进去
*
* @param userTypeServices {@link UserTypeService}所有的实现类
*/
public CenterUserHandleService(List<UserTypeService> userTypeServices) {
userTypeServices.forEach(userTypeService -> userTypeServiceEnumMap.put(userTypeService.getUserType(), userTypeService));
}
/**
* 获取折扣后金额
* @param userTypeEnum 用户类型枚举
* @param amount 原价
* @return 折扣后金额
*/
public Double getDiscountAmount(UserTypeEnum userTypeEnum,Double amount){
return userTypeServiceEnumMap.get(userTypeEnum).getDiscountAmount(amount);
}
}
看到这里之后,我相信聪明的你们应该已经知道UserTypeService的实现类该如何写了吧,话不多说直接上代码
/**
* 普通用户
* @author hys
* @date 2022/8/9 10:52
*/
@Service
public class CommonUserServiceImpl implements UserTypeService {
private static final double DISCOUNT = 0.9;
@Override
public UserTypeEnum getUserType() {
return UserTypeEnum.COMMON;
}
@Override
public Double getDiscountAmount(Double amount) {
return amount*DISCOUNT;
}
}
/**
* vip用户
* @author hys
* @date 2022/8/9 10:51
*/
@Service
public class VipUserServiceImpl implements UserTypeService {
private static final double DISCOUNT = 0.8;
@Override
public UserTypeEnum getUserType() {
return UserTypeEnum.VIP;
}
@Override
public Double getDiscountAmount(Double amount) {
return amount*DISCOUNT;
}
}
/**
* 超级vip用户
* @author hys
* @date 2022/8/9 10:41
*/
@Service
public class SuperVipUserServiceImpl implements UserTypeService {
private static final double DISCOUNT = 0.7;
@Override
public UserTypeEnum getUserType() {
return UserTypeEnum.SUPER_VIP;
}
@Override
public Double getDiscountAmount(Double amount) {
return amount*DISCOUNT;
}
}
测试
做完这些之后我们当然不能忘了测试一下啊,测试代码如下:
/**
* 用户策略模式测试
* @author hys
* @date 2022/8/9 10:54
*/
@RunWith(value = SpringRunner.class)
@SpringBootTest(classes = SpringBootDemoApplication.class)
public class UserStrategyModeTest {
@Autowired
private CenterUserHandleService centerUserHandleService;
@Test
public void testUserStrategy(){
double amount = 100.00;
//获取普通用户应支付金额
System.out.println(centerUserHandleService.getDiscountAmount(UserTypeEnum.COMMON,amount));
//获取vip用户应支付金额
System.out.println(centerUserHandleService.getDiscountAmount(UserTypeEnum.VIP,amount));
//获取超级vip用户应支付金额
System.out.println(centerUserHandleService.getDiscountAmount(UserTypeEnum.SUPER_VIP,amount));
}
}
结尾
其实在实际的开发中我们会经常遇到形形色色的问题,if else代码块也经常能为我们解决非常多的事,但是我希望你能多考虑一些优美解耦的写法,就以上问题而言,还有一种写法是使用HashMap结合Function的写法,也可以优美的解决,有兴趣的伙伴可以了解一下