如何干掉 if else 策略+工厂
2020-06-11 16:03:49来源:博客园 阅读 ()
如何干掉 if else 策略+工厂
无论我们做什么业务都无法避免 if else, 但是多重又会导致很多if,今天我们来讲讲如何干掉if else 让你摆脱被if else 支配的恐惧.
首先让我们来看看简单的if else 语句
public void test(TestUser testUser) {
if (Objects.isNull(testUser)){
System.out.println("执行业务 一");
} else {
System.out.println("执行业务 二");
}
}
并没有什么问题.但是如果业务稍微复杂一些呢,我们再来看看
首先贴出用户实体类
@Data
public class TestUser {
private Integer id;
private String name;
private Viplevel vipLevel;
}
在贴出用户VIP枚举
@Getter
@AllArgsConstructor
public enum Viplevel implements Serializable, IEnum {
NOVIP(0, "普通用户","普通用户"),
VIP_LEVEL1(1, "包月会员","包月会员"),
VIP_LEVEL2(2, "季度会员","季度会员"),
VIP_LEVEL3(3, "半年会员","半年会员"),
VIP_LEVEL4(4, "年费会员","年费会员");
private final Integer code;
private final String desc;
private final String msg;
@JsonCreator
public static Viplevel jsonCreator(Integer code) {
for (Viplevel value : Viplevel.values()) {
if (value.getCode().equals(code)) {
return value;
}
}
return null;
}
@JsonValue
public Map getResult() {
Map<String, Object> map = new LinkedHashMap<String, Object>();
map.put("code", getCode());
map.put("desc", getDesc());
map.put("msg", getMsg());
return map;
}
@Override
public Serializable getValue() {
return this.code;
}
}
再来看看业务
public double sellMoney(TestUser testUser) {
double proPrice = 3000;
double resultMoney = proPrice;
if (Objects.isNull(testUser)) {
//抛出异常
return proPrice;
} else {
if (Viplevel.NOVIP.equals(testUser.getVipLevel())) {
System.out.println("普通用户");
resultMoney = proPrice;
} else if (Viplevel.VIP_LEVEL1.equals(testUser.getVipLevel())) {
System.out.println("包月会员");
resultMoney = proPrice - 100;
} else if (Viplevel.VIP_LEVEL2.equals(testUser.getVipLevel())) {
System.out.println("季度会员");
resultMoney = proPrice - 300;
} else if (Viplevel.VIP_LEVEL3.equals(testUser.getVipLevel())) {
System.out.println("半年会员:");
resultMoney = proPrice * 0.8;
} else if (Viplevel.VIP_LEVEL4.equals(testUser.getVipLevel())) {
System.out.println("年会员:");
resultMoney = proPrice * 0.3;
}
return resultMoney;
}
}
天哪,这只是一个简单的例子,竟然出现如此多让人懊恼的语句.那么该如何解决呢,别着急,让我们一步步来干掉讨厌的 if else
首先思考,最终结果就是要获取到最终产品的售价,那我们就写个计算结果的方法,再让接口去继承他,这样不就能根据需求计算得到结果了吗
/**
* @author NYY
* @decription 普通用户最终产品售价
*/
public class NormalStrategy implements ComputeStrategy {
@Override
public double compute(double money) {
return money;
}
}
/**
* @author NYY
* @date 2020/6/4$
* @decription 月会员最后售价
*/
public class MonthStrategy implements ComputeStrategy {
@Override
public double compute(double money) {
return money - 100;
}
}
....以此类推
那么我们最终的业务实现是这样的
private static double getResultMoney(TestUser testUser) {
double proPrice = 3000;
double resultMoney = proPrice;
if (Objects.isNull(testUser)) {
//抛出异常
return proPrice;
} else {
if (Viplevel.NOVIP.equals(testUser.getVipLevel())) {
resultMoney = new NormalStrategy().compute(proPrice);
} else if (Viplevel.VIP_LEVEL1.equals(testUser.getVipLevel())) {
resultMoney = new MonthStrategy().compute(proPrice);
}
//......
}
return resultMoney;
}
在优化一下变成了这样
private static double getResultMoneyTwo(TestUser testUser) {
double proPrice = 3000;
double resultMoney = proPrice;
ComputeStrategy computeStrategy = null;
if (Objects.isNull(testUser)) {
//抛出异常
return proPrice;
} else {
if (Viplevel.NOVIP.equals(testUser.getVipLevel())) {
computeStrategy = new NormalStrategy();
} else if (Viplevel.VIP_LEVEL1.equals(testUser.getVipLevel())) {
computeStrategy = new MonthStrategy();
}
//......
//最后计算结果
return computeStrategy.compute(proPrice);
}
}
什么,if else 居然还在,我们发现,它需要的不仅是计算结果,主要是根据用户类型,好吧,那我们吧用户类型也提出来
public interface ComputeStrategyTwo {
// 计算方法
double compute(double money);
//获取用户类型
Integer getUserType();
}
接口继承时实现这两个方法
新增的 getUserType
方法,主要用来标示
该策略的type
值。
/**
* @author NYY
* @decription 普通用户
*/
public class NewNormalStrategy implements ComputeStrategyTwo{
@Override
public double compute(double money) {
return money;
}
@Override
public Integer getUserType() {
return Viplevel.NOVIP.getCode();
}
}
/**
* @author NYY
* @decription 月会员最后售价
*/
public class NewMonthStrategy implements ComputeStrategyTwo {
@Override
public double compute(double money) {
return money - 100;
}
@Override
public Integer getUserType() {
return Viplevel.VIP_LEVEL1.getCode();
}
}
重点又来了,这时我们就再把策略的工厂加进来
/**
* @author NYY
* @decription
*/
public class ComputeStrategyFactory {
private Map<Integer, ComputeStrategyTwo> map;
public ComputeStrategyFactory() {
List<ComputeStrategyTwo> strategies = new ArrayList<>();
strategies.add(new NewNormalStrategy());//普通用户
strategies.add(new NewMonthStrategy());//包月用户
//.......
// java 8 stream流
map = strategies.stream().collect(Collectors.toMap(ComputeStrategyTwo::getUserType, computeStrategy -> computeStrategy));
}
public static class Possessor {
public static ComputeStrategyFactory instance = new ComputeStrategyFactory();
}
public static ComputeStrategyFactory getInstance() {
return Possessor.instance;
}
public ComputeStrategyTwo get(Integer type) {
ComputeStrategyTwo computeStrategyTwo = map.get(type);
return computeStrategyTwo;
}
}
这样我们策略的工厂也有了.最终让我们看看处理业务的代码变成什么样了呢.
private static double lastResultMoney(TestUser testUser){
double proPrice = 3000;
Objects.requireNonNull(testUser,"用户对象为空了");
ComputeStrategyTwo computeStrategyTwo = ComputeStrategyFactory.getInstance().get(testUser.getVipLevel().getCode());
if(Objects.isNull(computeStrategyTwo)){
// throw new GlobalException("用户类型未知");
// 抛出全局异常
}
return computeStrategyTwo.compute(proPrice);
}
怎么样 最终我们通过策略+工厂的方式实现了业务,再也没看见令人讨厌的if else 语句.
至此完结 !!! 文章未经博主同意禁止转载,转载请赋连接
原文链接:https://www.cnblogs.com/Java-zhitu/p/13090537.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
下一篇:与JAVA集合相遇
- Flink 如何分流数据 2020-06-11
- 老板让你抗住千万级流量,如何做架构设计? 2020-06-11
- 类的继承,方法重新中修饰符如何定义 2020-06-10
- 如何写出高质量Spring 组件? 2020-06-08
- 如何优雅地停止 Spring Boot 应用? 2020-06-08
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash