状态模式是一种行为设计模式,它允许在对象内部状态发生改变时改变其行为。该模式将状态封装在独立的类中,使得每个状态对象可以处理不同的对象行为,从而实现对象行为的随状态改变而改变。
在状态模式中,有三种角色:
- Context(上下文):上下文是一个拥有状态的对象。它维护了一个指向具体状态的引用,以便于上下文内部状态的切换。
- State(状态):状态是一个接口,它定义了一个在特定状态下执行的操作(行为)。
- ConcreteState(具体状态):实现State接口的类。
下面是一个使用C#实现状态模式的例子,假设有一个订单类,它有以下三种状态:新建状态、已支付状态和已取消状态。通过状态模式,我们可以在订单状态切换时改变订单对象的行为,比如不同状态下能否对订单进行修改等:
代码语言:javascript复制// State接口定义订单状态的操作
public interface IOrderState
{
void HandlePayment();
void ShipOrder();
}
// Order类作为上下文,维护着State状态
public class Order
{
public string Name { get; set; }
public decimal TotalPrice { get; set; }
public bool IsPaid { get; set; }
public bool IsCancelled { get; set; }
private IOrderState _state;
// Constructor
public Order()
{
_state = new NewOrderState(this);
}
// Property to get or set the current Order state
public IOrderState State
{
get { return _state; }
set { _state = value; }
}
// Behavior method to handle payment
public void HandlePayment()
{
_state.HandlePayment();
}
// Behavior method to ship the order
public void ShipOrder()
{
_state.ShipOrder();
}
}
// ConcreteState1:新建订单状态
public class NewOrderState : IOrderState
{
private readonly Order _order;
public NewOrderState(Order order)
{
_order = order;
}
public void HandlePayment()
{
_order.State = new PaidOrderState(_order);
}
public void ShipOrder()
{
Console.WriteLine("Cannot ship the order as it is not yet paid.");
}
}
// ConcreteState2:已支付订单状态
public class PaidOrderState : IOrderState
{
private readonly Order _order;
public PaidOrderState(Order order)
{
_order = order;
}
public void HandlePayment()
{
Console.WriteLine("Payment has already been received.");
}
public void ShipOrder()
{
Console.WriteLine("Order shipped.");
_order.State = new ShippedOrderState(_order);
}
}
// ConcreteState3:已取消订单状态
public class CancelledOrderState : IOrderState
{
private readonly Order _order;
public CancelledOrderState(Order order)
{
_order = order;
}
public void HandlePayment()
{
Console.WriteLine("Cannot receive payment as the order has been cancelled.");
}
public void ShipOrder()
{
Console.WriteLine("Cannot ship the order as it has been cancelled.");
}
}
// ConcreteState4:已发货订单状态
public class ShippedOrderState : IOrderState
{
private readonly Order _order;
public ShippedOrderState(Order order)
{
_order = order;
}
public void HandlePayment()
{
Console.WriteLine("Cannot receive payment as the order has already been shipped.");
}
public void ShipOrder()
{
Console.WriteLine("Cannot ship the order as it has already been shipped.");
}
}
使用示例:
代码语言:javascript复制Order order = new Order()
{
Name = "Order1",
TotalPrice = 100,
};
// Handle payment for the order
order.HandlePayment();
// Ship the order
order.ShipOrder();
// Cancel the order
order.State = new CancelledOrderState(order);
输出结果:
代码语言:javascript复制Order shipped.
Cannot receive payment as the order has been cancelled.