Java设计模式之状态模式
由之前的一周两更变成了一更,哈哈哈,最近多了一些快乐,时间总是固定的,投入一件事情的多了,另外的事情就会少,本周大概率还是一篇了,emmmm,以后会尽量减少无意义的快乐,找到真正的意义,嗯,就说这么多,下面来看下什么是状态模式
一 : 什么是状态模式 ?
状态模式 : 当一个对象的内在状态改变是允许改变其行为,这个对象看起来像是改变了其类
状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化
二: 模式实现原理
1. 模式的角色 :
抽象状态类(State) : 定义一个接口以封装与context的一个状态相关的行为
具体状态(ConcreteState): 每一子类实现一个与Context的一个状态相关的行为
状态上下文 (Context) : 维护一个ConcreteState子类的实例,这个实例定义当前的状态。
2. 模式的结构
三: 代码实现
代码类图 :
本次使用案例是一个价格折扣的案例 :
超市在新开业期间对于不同的实际消费进行打折活动,500以下的打九折,500 ~ 1000 期间的打八折,超过1000的打七折
这里state类是抽象类,下面有三个实现类,分别对应不同的折扣逻辑.context是状态上下文,主要是维护折扣子类的状态
步骤一 : 抽象状态类
/**
* @version 1.0.0
* @Description 抽象状态类 : 获取折扣
*/
@Data
public abstract class State {
protected Context context;
/**
* 获取折扣后价格
* @param price 当前价格
* @return 折扣后价格
*/
public abstract BigDecimal getDiscount(BigDecimal price);
}
步骤二 : 状态上下文
/**
* @version 1.0.0
* @Description 状态上下文
*/
@Data
public class Context {
/**
* 抽象状态父类
*/
private State state;
/**
* 原价
*/
private BigDecimal price;
public BigDecimal getPrice(){
BigDecimal stateDiscount = this.state.getDiscount(price);
return stateDiscount;
}
}
步骤三 : 具体状态类 : 九折
/**
* @version 1.0.0
* @Description 具体状态 : 九折
*/
public class FirstDiscount extends State {
@Override
public BigDecimal getDiscount(BigDecimal price) {
BigDecimal priceDiscount = null;
BigDecimal decimal = new BigDecimal(500);
int i = price.compareTo(decimal);
if (i > 0){
SecondDiscount secondDiscount = new SecondDiscount();
priceDiscount = secondDiscount.getDiscount(price);
}else {
priceDiscount = price.multiply(new BigDecimal(String.valueOf(0.9)));
}
return priceDiscount;
}
}
具体状态类 :八折
/**
* @version 1.0.0
* @Description 具体状态 : 八折
*/
public class SecondDiscount extends State {
@Override
public BigDecimal getDiscount(BigDecimal price) {
BigDecimal priceDiscount = null;
BigDecimal decimal = new BigDecimal(1000);
int i = price.compareTo(decimal);
if (i > 0){
ThirdDiscount thirdDiscount = new ThirdDiscount();
priceDiscount = thirdDiscount.getDiscount(price);
}else {
priceDiscount = price.multiply(new BigDecimal(String.valueOf(0.8)));
}
return priceDiscount;
}
}
具体状态类 : 七折
/**
* @version 1.0.0
* @Description 具体状态 : 七折
*/
public class ThirdDiscount extends State {
@Override
public BigDecimal getDiscount(BigDecimal price) {
return price.multiply(new BigDecimal(String.valueOf(0.7)));
}
}
步骤四 : 测试类
/**
* @version 1.0.0
* @Description 状态模式测试类
*/
public class StateTest {
public static void main(String[] args) {
Context context = new Context();
context.setState(new FirstDiscount());
context.setPrice(new BigDecimal(300));
BigDecimal price = context.getPrice();
System.out.println("折扣后价格为 : " + price);
System.out.println("===========================================");
context.setPrice(new BigDecimal(800));
BigDecimal second = context.getPrice();
System.out.println("折扣后价格为 : " + second);
System.out.println("===========================================");
context.setPrice(new BigDecimal(2000));
BigDecimal third = context.getPrice();
System.out.println("折扣后价格为 : " + third);
}
}
测试 :
折扣后价格为 : 270.0
===========================================
折扣后价格为 : 640.0
===========================================
折扣后价格为 : 1400.0
四 总结 :
观察者模式的适用场景 :
当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式
观察者模式的优缺点 :
优点 :
1 . 通过把各种状态转移逻辑分布到抽象状态类的子类之间,减少相互间的依赖
2 . 通过定义新的子类可以很容易的增加新的状态和转换
缺点 :
1 . 状态模式的使用必然会增加系统类和对象的个数。
2 . 对"开闭原则"的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的代码
状态模式和策略模式的区别 :
https://zhuanlan.zhihu.com/p/142056182
关于区别这一块从网上找的相关资料,大家有兴趣可以深入了解一下
对状态模式的学习就记录这么多,如果对大家有帮助的话,可以点一个赞哈,你的鼓励也是创作的动力.共同在计算机的世界加油吧 !