状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的状况。把状态的判断逻辑转移到表示不一样状态的一系列类当中,能够把复杂的判断逻辑简化.java
一个复杂的业务中可能存在大量的 if else等逻辑条件判断,对于后期维护来讲是很是危险和复杂的。而状态模式也是将与特定状态相关的行为局部化,而且将不一样状态的行为分割开来.bash
能够消除大量的条件分支语句,内部经过状态转移,来减小之间的相互依赖markdown
好比你在参与百度网盘开发,有如下常见场景:post
会员等级 | 权限 |
---|---|
普通用户 | 存储照片、文件 |
会员 | 极速下载、5T空间... |
超级会员 | 小视频自动备份、音视频倍速播放... |
权限获取类优化
package design.pattern; import java.util.ArrayList; public class UserRule { /** * 等级 1普通用户 2会员 3超级会员 */ private Integer level = 1; /** * 权限容器 */ private ArrayList<String> ruleList = new ArrayList<String>() { { add("上传文件"); add("下载文件"); } }; public UserRule(Integer level) { this.level = level; } /** * 获取权限列表 * * @return */ public ArrayList<String> getRuleList() { if (this.level == 2) { //会员 //todo 权限获取 ruleList.add("极速下载"); ruleList.add("5T空间"); } else if (this.level == 3) { //超级会员 //todo 权限获取 ruleList.add("光速下载"); ruleList.add("10T空间"); ruleList.add("小视频自动备份"); ruleList.add("音视频倍速播放"); } return ruleList; } } 复制代码
客户端调用:this
Integer requestLevel = 3; UserRule userRule = new UserRule(requestLevel); ArrayList<String> ruleList = userRule.getRuleList(); //打印权限 System.out.println("会员等级" + requestLevel + "权限列表:"); for (Object object : ruleList) { System.out.println(object); } 复制代码
output:spa
会员等级3权限列表:
上传文件
下载文件
光速下载
10T空间
小视频自动备份
音视频倍速播放
复制代码
彷佛看起来咱们的代码足够简单,很好的知足了根据等级返回权限的需求code
咱们重点关注下获取权限列表的根据不一样的条件分支,处理不一样的todo 的业务逻辑,若是咱们加入了更多的等级,更复杂的权限计算方式等等功能, 这个if else将会更加的庞大起来.orm
刚刚说完可能庞大起来,产品过来又给我提v2.0的需求.视频
咱们发现若是再加上返回下个版本的权限,真的是够了,再过几天不必定又出什么需求,这个方法看起来都要崩溃了. 看来须要优化一下了。
首先咱们创建一个抽象类(核心做用方便子类约束和传递)
State.java
package design.pattern.Rules; import design.pattern.UserRule; import design.pattern.UserVo; import java.util.ArrayList; public abstract class State { /** * 用户对象 */ protected UserRule userRule; /** * 权限容器 */ protected ArrayList<String> ruleList = new ArrayList<String>() { { add("上传文件"); add("下载文件"); } }; public State(UserRule userRule) { this.userRule = userRule; } public abstract ArrayList<String> getRuleList(UserVo userVo); } 复制代码
第一步咱们须要简单的参数对象(这里用view object)
UserVo.java
package design.pattern; public class UserVo { private String name; private Integer level; public UserVo(String name, Integer level) { this.name = name; this.level = level; } public String getName() { return name; } public Integer getLevel() { return level; } } 复制代码
继承State.java状态类,实现各自的会员返回类
package design.pattern.Rules; import design.pattern.UserRule; import design.pattern.UserVo; import java.util.ArrayList; /** * 一类会员 */ public class MemberOne extends State { public MemberOne(UserRule userRule) { super(userRule); } /** * 获取权限列表 * * @return */ public ArrayList<String> getRuleList(UserVo userVo) { //若是是一类会员(普通) if (userVo.getLevel() == 1) { return ruleList; } else { userRule.setState(new MemberTwo(userRule)); //设置下一级别类 return userRule.getRuleList(userVo); //获取下一个级别的详情 } } } 复制代码
UserRule.java (桥梁类)
package design.pattern; import design.pattern.Rules.MemberOne; import design.pattern.Rules.State; import java.util.ArrayList; public class UserRule { /** * 具体权限对象 */ private State currentRule; public UserRule() { currentRule = new MemberOne(this); } /** * 设置权限对象 * * @param state */ public void setState(State state) { this.currentRule = state; } public ArrayList<String> getRuleList(UserVo userVo) { return this.currentRule.getRuleList(userVo); } } 复制代码
userRule类为咱们优化前充满了条件判断的类,对他进行了解耦合.能够理解为对内调用类,对外暴露类的桥梁类
userVo对象是咱们的参数对象,这里主要用于等级判断. 若是不成立,则进行从新设置下一个处理规则类,并一样调用规则列表方法。
剩下的两个会员类
package design.pattern.Rules; import design.pattern.UserRule; import design.pattern.UserVo; import java.util.ArrayList; /** * 三类会员 */ public class MemberTwo extends State { public MemberTwo(UserRule userRule) { super(userRule); } /** * 获取权限列表 * * @return */ public ArrayList<String> getRuleList(UserVo userVo) { if (userVo.getLevel() == 2) { ruleList.add("极速下载"); ruleList.add("5T空间"); return ruleList; }else{ userRule.setState(new MemberThree(userRule)); return userRule.getRuleList(userVo); } } } 复制代码
package design.pattern.Rules; import design.pattern.UserRule; import design.pattern.UserVo; import java.util.ArrayList; /** * 三类会员 */ public class MemberThree extends State { public MemberThree(UserRule userRule) { super(userRule); } /** * 获取权限列表 * * @return */ public ArrayList<String> getRuleList(UserVo userVo) { //最高级 ruleList.add("光速下载"); ruleList.add("10T空间"); ruleList.add("小视频自动备份"); ruleList.add("音视频倍速播放"); return ruleList; } } 复制代码
为了参数方便传递管理,咱们单独使用一个view object类.
UserVo.java
package design.pattern; public class UserVo { private String name; private Integer level; public UserVo(String name, Integer level) { this.name = name; this.level = level; } public String getName() { return name; } public Integer getLevel() { return level; } public void setName(String name) { this.name = name; } public void setLevel(int level) { this.level = level; } } 复制代码
客户端调用:
UserVo userVo = new UserVo("小红", 1); UserRule userRule = new UserRule(); ArrayList<String> ruleList = userRule.getRuleList(userVo); //打印 System.out.println("用户" + userVo.getName() + "当前权限以下:"); for (Object object : ruleList) { System.out.println(object); } //他的下个权限能够得到 userVo.setLevel(userVo.getLevel() + 1); ruleList = userRule.getRuleList(userVo); System.out.println("用户" + userVo.getName() + "将要权限以下:"); for (Object object : ruleList) { System.out.println(object); } 复制代码
output:
用户小红当前权限以下:
上传文件
下载文件
用户小红将要权限以下:
上传文件
下载文件
极速下载
5T空间
复制代码
if (userVo.getLevel() == 1) { return ruleList; } else { userRule.setState(new MemberTwo(userRule)); //设置下一级别类 return userRule.getRuleList(userVo); //获取下一个级别的详情 } 复制代码
思考这段代码存在的问题? 如何优化?
策略模式与状态模式极其类似,可是两者有其内在的差异
userRule.setState(new MemberTwo(userRule));),
复制代码
对比策略模式: 策略模式详解
更多精彩内容请关注热情小宇公众号(呆呆熊一点通)