设计模式——状态模式
1- 状态模式的定义
在状态模式中,类的行为是基于它的状态而改变的,这种类型的设计模式就是状态模式。在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的Context对象。在实际开发中,我们经常会遇到这样的一种情况:一个对象有一个表示状态的属性,一般会定义成一个枚举表示这个状态,在数据库中存储成tinyint类型的值,在业务代码中定义一个枚举表示各个值表示含义,通常需要根据对象的状态值的不同做出不同的处理,一般可能会有一堆的if-elseif-else代码,看上去就不优雅,而且如果业务逻辑需要变动的话就需要修改if-elseif-else中的代码,容易出错!所以一般这种根据状态不同采用不同的处理逻辑的业务模式,可以采用状态模式!
No BB,Show Code!
2- 状态模式的实现代码
2-1准备工作
为了更好的理解状态模式,定义了一个pojo、一个枚举值和一个表示处理结果的对象代码如下:
定义了Order类,表示订单,status表示订单的状态
package designPattern.test.state;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* 订单类,需要处理的对象
*/
public class Order implements Serializable {
//订单编号
private String orderNo;
//下单人
private String buyer;
//订单状态(0-新建,1-处理中,2-完成,3-取消)
private Byte status;
//金额
private BigDecimal money;
//下单时间
private Date createTime;
public Order(){}
public Order(String orderNo, String buyer, Byte status, BigDecimal money, Date createTime) {
this.orderNo = orderNo;
this.buyer = buyer;
this.status = status;
this.money = money;
this.createTime = createTime;
}
public String getOrderNo() {
return orderNo;
}
public void setOrderNo(String orderNo) {
this.orderNo = orderNo;
}
public String getBuyer() {
return buyer;
}
public void setBuyer(String buyer) {
this.buyer = buyer;
}
public Byte getStatus() {
return status;
}
public void setStatus(Byte status) {
this.status = status;
}
public BigDecimal getMoney() {
return money;
}
public void setMoney(BigDecimal money) {
this.money = money;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
}
定义一个枚举,OrderStatusEnum
package designPattern.test.state;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
/**
* 订单状态枚举
*/
public enum OrderStateEnum {
NEW((byte) 0, "新建"),
HANDLING((byte) 1, "处理中"),
FINISHED((byte) 2, "完成"),
CANCEL((byte) 3, "取消");
public static final Map<Byte, OrderStateEnum> orderStateEnumMap = new HashMap<Byte, OrderStateEnum>();
static {
for (OrderStateEnum e : EnumSet.allOf(OrderStateEnum.class)) {
orderStateEnumMap.put(e.getKey(), e);
}
}
public static OrderStateEnum getByCode(Byte code) {
return orderStateEnumMap.get(code);
}
private Byte key;
private String text;
private OrderStateEnum(Byte key, String text) {
this.key = key;
this.text = text;
}
public Byte getKey() {
return key;
}
public void setKey(Byte key) {
this.key = key;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
定义处理结果对象Resultpackage designPattern.test.state;
import java.io.Serializable;
/**
* 处理结果
*/
public class Result implements Serializable {
private int resultCode;
private String resultMsg;
private Object resultValue;
public Result() {
}
public Result(int resultCode, String resultMsg, Object resultValue) {
this.resultCode = resultCode;
this.resultMsg = resultMsg;
this.resultValue = resultValue;
}
public int getResultCode() {
return resultCode;
}
public void setResultCode(int resultCode) {
this.resultCode = resultCode;
}
public String getResultMsg() {
return resultMsg;
}
public void setResultMsg(String resultMsg) {
this.resultMsg = resultMsg;
}
public Object getResultValue() {
return resultValue;
}
public void setResultValue(Object resultValue) {
this.resultValue = resultValue;
}
}
2-2定义订单状态接口
订单状态接口OrderState
package designPattern.test.state;
/**
* 订单状态接口
*/
public interface OrderState {
/**
* 订单处理方法,每一种订单状态都有对应的处理方法
*/
Result handle(Order order);
}
2-3定义订单状态接口实现类
每一种订单状态都对应一个订单状态的实现类,表示该订单状态的订单的处理逻辑!
1-新建订单状态处理逻辑,NewOrderStateImpl
package designPattern.test.state;
import com.google.common.base.Preconditions;
/**
* 新建订单状态的行为
*/
public class NewOrderStateImpl implements OrderState {
/**
* 新建订单的处理逻辑
*/
@Override
public Result handle(Order order) {
Preconditions.checkNotNull(order);
System.out.println("新建订单处理......");
order.setStatus(OrderStateEnum.HANDLING.getKey());
return new Result(1, "success", order);
}
}
2-处理中订单处理逻辑
package designPattern.test.state;
import com.google.common.base.Preconditions;
/**
* 处理中订单处理逻辑
*/
public class HandlingOrderStateImpl implements OrderState{
/**
* 处理中订单处理逻辑
*/
@Override
public Result handle(Order order) {
Preconditions.checkNotNull(order);
System.out.println("处理中订单处理......");
order.setStatus(OrderStateEnum.FINISHED.getKey());
return new Result(1, "success", order);
}
}
3-完成订单状态处理逻辑
package designPattern.test.state;
import com.google.common.base.Preconditions;
/**
* 完成订单状态的行为
*/
public class FinishedOrderStateImpl implements OrderState {
/**
* 完成订单的处理逻辑
*/
@Override
public Result handle(Order order) {
Preconditions.checkNotNull(order);
System.out.println("完成订单处理......");
return new Result(1, "success", order);
}
}
4-取消订单状态处理逻辑
package designPattern.test.state;
import com.google.common.base.Preconditions;
/**
* 取消订单状态的行为
*/
public class CancelOrderStateImpl implements OrderState {
/**
* 取消订单的处理逻辑
*/
@Override
public Result handle(Order order) {
Preconditions.checkNotNull(order);
System.out.println("取消订单处理......");
return new Result(1, "success", order);
}
}
3- 测试
测试代码如下
package designPattern.test.state;
import com.google.common.base.Preconditions;
import org.junit.Assert;
import org.junit.Test;
import java.math.BigDecimal;
import java.util.Date;
/**
* 状态模式测试
*/
public class StateTest {
/**
* 模拟从数据库中查询出一个order,根据order的状态进行不同的处理
*/
@Test
public void testState() {
Order order = new Order("BJ10021", "ppp", OrderStateEnum.HANDLING.getKey(), new BigDecimal(100), new Date());
OrderState orderState = getOrderState(order);
Result result = orderState.handle(order);
Assert.assertTrue(result.getResultCode() == 1);
}
/**
* 根据订单的状态获取对应的OrderState具体实现类
*/
private OrderState getOrderState(Order order) {
Preconditions.checkNotNull(order);
switch (OrderStateEnum.getByCode(order.getStatus())) {
case NEW:
return new NewOrderStateImpl();
case HANDLING:
return new HandlingOrderStateImpl();
case FINISHED:
return new FinishedOrderStateImpl();
case CANCEL:
return new CancelOrderStateImpl();
default:
throw new RuntimeException("The state of order is wrong!");
}
}
}
总结:状态模式特别适合于业务逻辑中某个对象根据不同状态的进行不同复杂业务逻辑处理的场景,此时就没有了大块大块的if-elseif-else的代码了,如果状态有变化,需要加一个状态接口的实现类即可!缺点就是类变的多了…..