读书笔记:headfirst 设计模式 ,大话设计模式,相关技术博客等
用一个大家都熟悉的网购订单状态(简化版)来解释状态模式
首先不使用状态模式时的代码
// 测试类
public class SimpleStateTest {
public static void main(String[] args) {
Buyer buyer = new Buyer();
buyer.setName("小明");
Saler saler = new Saler();
saler.setName("王老板");
// 创建普通订单
SimpleOrder order = new SimpleOrder("001",buyer, saler);
// 买家付款
order.buyerPay();
// 卖家发货
order.SalerSendOut();
// 买家取消订单
order.BuyerCancel();
// 买家收货
order.BuyerReceive();
}
}
测试结果:
创建新订单 001(买家:小明 卖家:王老板) →当前订单状态为未付款状态
买家:小明 已付款 →当前订单状态为已付款状态
卖家:王老板 已发货 →当前订单状态为待收货&已发货状态
!非法状态 无法取消订单
买家:小明已确认收货 →当前订单状态为已完成状态
具体代码↓
// 买家
public class Buyer {
private String name;
public String getName() {
return "买家:"+name;
}
public void setName(String name) {
this.name = name;
}
}
// 卖家
public class Saler {
private String name;
public String getName() {
return "卖家:"+name;
}
public void setName(String name) {
this.name = name;
}
}
// 订类
public class SimpleOrder {
// 状态订单枚举
public static enum State {
NON_PAY("未付款"), PAID("已付款"), RECEIVING("待收货&已发货"), COMPLETED("已完成"), CLOSED("已取消");
private String name;
State(String name) {
this.name = name;
}
public String getName() {
return name + "状态 ";
}
}
// 构造方法 订单号 买家 卖家
public SimpleOrder(String num, Buyer buyer, Saler saler) {
this.num = num;
this.buyer = buyer;
this.saler = saler;
System.out.print("创建新订单 " + num + "(" + buyer.getName() + " " + saler.getName() + ")");
setOrderState(State.NON_PAY);
}
// 订单编号
private String num;
// 买家
private Buyer buyer;
// 卖家
private Saler saler;
// 订单状态
private State orderState;
public void setOrderState(State orderState) {
this.orderState = orderState;
showState();
}
// 买家付款
public void buyerPay() {
switch (this.orderState) {
case NON_PAY:
System.out.print(buyer.getName() + " 已付款");
this.setOrderState(State.PAID);
break;
case PAID:
System.out.print(buyer.getName() + " 再次付款");
break;
case RECEIVING:
System.out.print("!非法状态 无法付款");
break;
case COMPLETED:
System.out.print("!非法状态 无法付款");
break;
case CLOSED:
System.out.print("!非法状态 无法付款");
break;
default:
System.out.print("!非法状态 非法状态");
break;
}
}
// 卖家发货
public void SalerSendOut() {
switch (this.orderState) {
case NON_PAY:
System.out.print(State.NON_PAY.getName() + saler.getName() + "无法发货");
this.setOrderState(State.PAID);
break;
case PAID:
System.out.print(saler.getName() + " 已发货");
this.setOrderState(State.RECEIVING);
break;
case RECEIVING:
System.out.print("!非法状态 无法发货");
break;
case COMPLETED:
System.out.print("!非法状态 无法发货");
break;
case CLOSED:
System.out.print("!非法状态 无法发货");
break;
default:
System.out.print("!非法状态 非法状态");
break;
}
}
// 买家收货
public void BuyerReceive() {
switch (this.orderState) {
case NON_PAY:
System.out.print("!非法状态 无法收货");
break;
case PAID:
System.out.print("!非法状态 无法收货");
break;
case RECEIVING:
System.out.print(buyer.getName() + "已确认收货");
this.setOrderState(State.COMPLETED);
break;
case COMPLETED:
System.out.print("!非法状态 无法收货");
break;
case CLOSED:
System.out.print("!非法状态 无法收货");
break;
default:
System.out.print("!非法状态 无法收货");
break;
}
}
// 买家取消订单
public void BuyerCancel() {
switch (this.orderState) {
case NON_PAY:
System.out.print(buyer.getName() + "取消订单");
this.setOrderState(State.CLOSED);
break;
case PAID:
System.out.print(buyer.getName() + "取消订单 付款金额已退回买家账户");
this.setOrderState(State.RECEIVING);
break;
case RECEIVING:
System.out.println("!非法状态 无法取消订单");
break;
case COMPLETED:
System.out.print("!非法状态 无法取消订单");
break;
case CLOSED:
System.out.print("!非法状态 无法取消订单");
break;
default:
System.out.print("!非法状态 无法取消订单");
break;
}
}
// 卖家买家取消订单
public void SalerCancel() {
switch (this.orderState) {
case NON_PAY:
System.out.print(saler.getName() + "取消订单");
this.setOrderState(State.CLOSED);
break;
case PAID:
System.out.print(saler.getName() + "取消订单 买家付款金额已退回买家账户");
this.setOrderState(State.RECEIVING);
break;
case RECEIVING:
System.out.print("!非法状态 无法取消订单");
break;
case COMPLETED:
System.out.print("!非法状态 无法取消订单");
break;
case CLOSED:
System.out.print("!非法状态 无法取消订单");
break;
default:
System.out.print("!非法状态 无法取消订单");
break;
}
}
// 展示当前订单状态
private void showState() {
System.out.print(" →当前订单状态为" + this.orderState.getName());
System.out.println();
}
}
PS: 我们看到代码中许多switch(if else),如果现在想加入一个退货中状态会很麻烦,每个判断分支都需要再编写新状态的判断逻辑,状态模式就是解决这个问题的
概念:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类
类图
代码
// 测试类
public class StateTest {
public static void main(String[] args) {
Buyer buyer = new Buyer();
buyer.setName("小明");
Saler saler = new Saler();
saler.setName("王老板");
// 创建使用状态模式的订单
Order order = new Order("001",buyer, saler);
// 买家付款
order.buyerPay();
// 卖家发货
order.SalerSendOut();
// 买家取消订单
order.BuyerCancel();
// 买家收货
order.BuyerReceive();
}
}
结果:
创建新订单 001(买家:小明 卖家:王老板) →当前订单状态为未付款
买家:小明 已付款 →当前订单状态为已付款
卖家:王老板 已发货 →当前订单状态为收货中
!收货中:买家:小明无法取消订单 可以选择退货
买家:小明已收货 →当前订单状态为已完成
//订单
public class Order {
//未付款
public static final NonPay NON_PAY= new NonPay();
//已付款
public static final Paid PAID = new Paid();
//待收货&已发货
public static final Receiving RECEIVING = new Receiving();
// 已完成
public static final Completed COMPLETED = new Completed();
// 已取消
public static final Closed CLOSED = new Closed();
public Order(String num,Buyer buyer, Saler saler ) {
this.num =num;
this.buyer = buyer;
this.saler = saler;
System.out.print("创建新订单 "+num+"("+buyer.getName() +" "+saler.getName()+")");
setOrderState(NON_PAY);
}
//订单编号
private String num;
// 买家
private Buyer buyer;
// 卖家
private Saler saler;
// 订单状态
private OrderState orderState;
public void setOrderState(OrderState orderState) {
this.orderState = orderState;
showState();
}
// 卖家付款
public void buyerPay() {
orderState.pay(this, buyer);
}
// 卖家发货
public void SalerSendOut() {
orderState.sendOut(this, saler);
}
// 买家收货
public void BuyerReceive() {
orderState.receive(this, buyer);
}
// 买家取消订单
public void BuyerCancel() {
orderState.cancel(this, buyer);
}
// 卖家买家取消订单
public void SalerCancel() {
orderState.cancel(this, saler);
}
// 展示当前订单状态
private void showState() {
System.out.print(" →当前订单状态为" + orderState.getStateName());
System.out.println();
}
}
// 订单状态接口
public interface OrderState {
// 获取状态名称
String getStateName();
// 买家付款
void pay(Order order,Buyer buyer);
// 卖家发货
void sendOut(Order order,Saler saler);
// 买家收货
void receive(Order order,Buyer buyer);
// 买家取消订单
void cancel(Order order,Buyer buyer);
// 卖家取消订单
void cancel(Order order,Saler saler);
// 买家退货
void sendOut(Order order,Buyer buyer);
// 卖家收货
void receive(Order order,Saler saler);
}
// 未付款
public class NonPay implements OrderState {
@Override
public String getStateName() {
return "未付款";
}
@Override
public void pay(Order order, Buyer buyer) {
System.out.print(buyer.getName() + " 已付款");
order.setOrderState(Order.PAID);
}
@Override
public void sendOut(Order order, Saler saler) {
System.out.println("未付款状态 " + saler.getName() + "无法发货");
}
@Override
public void receive(Order order, Buyer buyer) {
System.out.println("未付款状态 " + buyer.getName() + "无法收货");
}
@Override
public void cancel(Order order, Buyer buyer) {
System.out.println(buyer.getName()+" 取消了订单,订单被关闭");
order.setOrderState(Order.CLOSED);
}
@Override
public void cancel(Order order, Saler saler) {
System.out.println(saler.getName()+" 取消了订单,订单被关闭");
order.setOrderState(Order.CLOSED);
}
@Override
public void sendOut(Order order, Buyer buyer) {
System.out.println("未付款状态 " + buyer.getName() + "无法退货");
}
@Override
public void receive(Order order, Saler saler) {
System.out.println("未付款状态 " + saler.getName() + "无法确认收到退货");
}
}
// 已付款
public class Paid implements OrderState {
@Override
public String getStateName() {
return "已付款";
}
@Override
public void pay(Order order, Buyer buyer) {
System.out.println(buyer.getName()+"再次付款");
}
@Override
public void sendOut(Order order, Saler saler) {
System.out.print(saler.getName()+" 已发货");
order.setOrderState(Order.RECEIVING);
}
@Override
public void receive(Order order, Buyer buyer) {
System.out.println("卖家未发货 "+buyer.getName()+"无法收货");
}
@Override
public void cancel(Order order, Buyer buyer) {
System.out.println("!"+buyer.getName()+"取消订单 已付款金额会退回买家账户");
order.setOrderState(Order.CLOSED);
}
@Override
public void cancel(Order order, Saler saler) {
System.out.println("!"+saler.getName()+"取消订单 已付款金额会退回买家账户");
order.setOrderState(Order.CLOSED);
}
@Override
public void sendOut(Order order, Buyer buyer) {
System.out.println(buyer.getName()+"无法执行退货");
}
@Override
public void receive(Order order, Saler saler) {
System.out.println(saler.getName()+"无法执行确认收到退货");
}
}
// 收货中
public class Receiving implements OrderState {
@Override
public String getStateName() {
return "收货中";
}
@Override
public void pay(Order order, Buyer buyer) {
System.out.println(buyer.getName()+"无法再次付款");
}
@Override
public void sendOut(Order order, Saler saler) {
System.out.println(saler.getName()+"无法再次发货");
}
@Override
public void receive(Order order, Buyer buyer) {
System.out.print(buyer.getName()+"已收货");
order.setOrderState(Order.COMPLETED);
}
@Override
public void cancel(Order order, Buyer buyer) {
System.out.println("!"+getStateName()+":"+buyer.getName()+"无法取消订单 可以选择退货");
}
@Override
public void cancel(Order order, Saler saler) {
System.out.println("!"+getStateName()+":"+saler.getName()+"无法取消订单");
}
@Override
public void sendOut(Order order, Buyer buyer) {
System.out.println(getStateName()+":"+buyer.getName()+"无法发货");
}
@Override
public void receive(Order order, Saler saler) {
System.out.println(getStateName()+":"+saler.getName()+"无法确认收到退货");
}
}
// 已完成
public class Completed implements OrderState {
@Override
public String getStateName() {
return "已完成";
}
@Override
public void pay(Order order, Buyer buyer) {
System.out.println("订单已完成 无法付款");
}
@Override
public void sendOut(Order order, Saler saler) {
System.out.println("订单已完成 无法发货");
}
@Override
public void receive(Order order, Buyer buyer) {
System.out.println("订单已完成 无法收货");
}
@Override
public void cancel(Order order, Buyer buyer) {
System.out.println("订单已完成 无法取消");
}
@Override
public void cancel(Order order, Saler saler) {
System.out.println("订单已完成 无法取消");
}
@Override
public void sendOut(Order order, Buyer buyer) {
System.out.println("订单已完成 无法退货");
}
@Override
public void receive(Order order, Saler saler) {
System.out.println("订单已完成 无法确认收到退货");
}
}
// 已取消
public class Closed implements OrderState {
@Override
public String getStateName() {
return "已关闭";
}
@Override
public void pay(Order order, Buyer buyer) {
System.out.println("订单已关闭 无法付款");
}
@Override
public void sendOut(Order order, Saler saler) {
System.out.println("订单已关闭 无法发货");
}
@Override
public void receive(Order order, Buyer buyer) {
System.out.println("订单已关闭 无法收货");
}
@Override
public void cancel(Order order, Buyer buyer) {
System.out.println("订单已关闭 无法取消");
}
@Override
public void cancel(Order order, Saler saler) {
System.out.println("订单已关闭 无法取消");
}
@Override
public void sendOut(Order order, Buyer buyer) {
System.out.println("订单已关闭 无法退货");
}
@Override
public void receive(Order order, Saler saler) {
System.out.println("订单已关闭 无法确认收到退货");
}
}