public abstract class State
{
public abstract void WriteProgram(Work w);
}
//上午工作状态
public class ForenoonState : State
{
public override void WriteProgram(Work w)
{
//这里的判断就是决定要用那种行为展现出来,如果 不符合当前状态,那么就去到已经设置好的下一个具体状态类中进行相同的操作。
if (w.hour < 12)
{
Console.WriteLine("当前时间:{0}点 上午工作,精神百倍",w.Hour);
}
else
{
w.SetState(new NoonState());w.WriteProgram();
}
}
}
//中午工作状态
public class NoonState : State
{
public override void WriteProgram(Work w)
{
if (w.hour < 13)
{
Console.WriteLine("当前时间:{0}点 饿了,想吃饭;犯困,想睡觉。", w.Hour);
}
else
{
w.SetState(new AfternoonState()); w.WriteProgram();
}
}
}
//下午工作状态
public class AfternoonState : State
{
public override void WriteProgram(Work w)
{
if (w.hour < 17)
{
Console.WriteLine("当前时间:{0}点 下午状态还不错,继续努力", w.Hour);
}
else
{
w.SetState(new EveningState()); w.WriteProgram();
}
}
}
//晚上工作状态
public class EveningState : State
{
public override void WriteProgram(Work w)
{
if (w.finish )
{
w.SetState(new RestState());w.WriteProgram();//完成任务就转成下班状态
}
else
{
if (w.hour <21)
{
Console.WriteLine("当前时间:{0}点 加班了,加班人累啊", w.Hour);
}
else
{
w.SetState(new SleepingState()); w.WriteProgram();//超过21点,转入睡眠状态
}
}
}
}
//睡眠状态
public class SleepingState:State
{
public override void WriteProgram(Work w)
{
Console.WriteLine("当前时间:{0}点 不行了,睡着了", w.Hour);
}
}
//下班休息状态
public class RestState : State
{
public override void WriteProgram(Work w)
{
Console.WriteLine("当前时间:{0}点 不行了,睡着了", w.Hour);
}
}
具体工作类:
public class Work
{
public State current;
public Work()
{
current = new ForenoonState(); //初始化为上午9点开始上班
}
public double hour;//小时钟,状态转换的依据
public bool finish = false;//完成任务属性,是否能下班的依据
//这个方法主要就是把具体的状态类给进来,然后让下面的方法去使用
public void SetState(State s) //得到状态
{
current = s;
}
//下面这个方法从始至终都没有发生改变,改变是其内部具体的展现值。
public void WriteProgram()
{
current.WriteProgram(this);
}
}
// 上下文类
public class Context {
private State currentState;
public void setCurrentState(State state) {
this.currentState = state;
}
public void request() {
// 委托当前状态对象执行行为
currentState.handle();
}
}
// 具体状态类A
public class ConcreteStateA implements State {
// ...
@Override
public void handle() {
// 具体状态A的行为逻辑
// 状态转换及触发条件
if (/*触发条件*/) {
context.setCurrentState(new ConcreteStateB());
}
}
}
为了演示订单状态管理的状态模式业务代码,我将使用Java语言来实现。以下是一个简单的示例:
首先,我们定义订单状态接口 OrderState
,其中包含了处理订单状态的方法 handle()
:
// 订单状态接口
public interface OrderState {
void handle();
}
然后,我们创建具体的订单状态类,包括待支付状态、已支付状态、待发货状态和已发货状态。每个状态类实现了订单状态接口,并根据相应的状态实现了自己的行为逻辑。
// 待支付状态类
public class PendingPaymentState implements OrderState {
@Override
public void handle() {
System.out.println("当前订单状态:待支付");
// 处理待支付状态的逻辑
}
}
// 已支付状态类
public class PaidState implements OrderState {
@Override
public void handle() {
System.out.println("当前订单状态:已支付");
// 处理已支付状态的逻辑
}
}
// 待发货状态类
public class ToBeShippedState implements OrderState {
@Override
public void handle() {
System.out.println("当前订单状态:待发货");
// 处理待发货状态的逻辑
}
}
// 已发货状态类
public class ShippedState implements OrderState {
@Override
public void handle() {
System.out.println("当前订单状态:已发货");
// 处理已发货状态的逻辑
}
}
接下来,我们创建订单类 Order
,它包含了当前订单状态和一些操作方法。
// 订单类
public class Order {
private OrderState currentState; // 当前订单状态
public Order() {
currentState = new PendingPaymentState(); // 默认初始状态为待支付
}
public void setCurrentState(OrderState state) {
currentState = state;
}
public void request() {
currentState.handle();
}
}
最后,我们可以进行测试,模拟订单在不同状态下的行为变化:
public class Main {
public static void main(String[] args) {
Order order = new Order(); // 创建订单
// 待支付状态
order.request();
// 支付订单,状态转换为已支付
order.setCurrentState(new PaidState());
order.request();
// 发货,状态转换为待发货
order.setCurrentState(new ToBeShippedState());
order.request();
// 完成发货,状态转换为已发货
order.setCurrentState(new ShippedState());
order.request();
}
}
以上示例演示了订单状态管理的状态模式业务代码。通过状态模式,我们可以根据订单状态的变化触发不同的行为逻辑,并且可以方便地添加新的订单状态,以满足业务需求。
策略模式和状态模式都属于行为型设计模式,它们都关注对象在不同的情境下具有不同的行为。虽然它们有相似之处,但在设计意图、应用场景和实现方式上存在一些差异。
下面是策略模式和状态模式的对比与联系:
对比:
设计意图:策略模式旨在通过定义一组算法或策略,并将其封装成独立的对象,使得这些算法可以互换使用。状态模式旨在让一个对象在其内部状态改变时改变其行为,从而实现状态之间的转换。
关注点:策略模式主要关注算法的选择和封装,使得具体的策略可以独立于客户端进行变化。状态模式主要关注对象的状态的管理和转换,以及不同状态下的行为执行。
对象角色:策略模式通常包含一个上下文类(Context)和一组策略类(Strategies),客户端与上下文类进行交互。状态模式通常包含一个上下文类(Context)和一组状态类(States),客户端与上下文类进行交互。
联系:
行为的封装:策略模式和状态模式都将行为封装到独立的对象中,使得行为可以被动态地变化。
对象之间的互动:策略模式和状态模式都需要一个上下文类(Context)来与策略对象或状态对象进行交互,并将具体的行为委托给策略对象或状态对象来执行。
可扩展性:策略模式和状态模式都具有较好的可扩展性。在策略模式中,可以方便地新增、修改或切换不同的策略对象。在状态模式中,可以方便地新增、修改或切换不同的状态对象。
总的来说,策略模式和状态模式都是强调对象行为的灵活性和可扩展性的设计模式。它们的主要区别在于策略模式关注算法的选择和封装,而状态模式关注对象状态的管理和转换。根据具体的需求,选择适合的模式来提高代码的可维护性和可扩展性。
下面是一个示例,演示了如何结合工厂模式和状态模式来管理订单的状态:
首先,定义订单状态接口 OrderState
和具体的订单状态类,与之前的示例相同。
// 订单状态接口
public interface OrderState {
void handle();
}
// 待支付状态类
public class PendingPaymentState implements OrderState {
@Override
public void handle() {
System.out.println("当前订单状态:待支付");
// 处理待支付状态的逻辑
}
}
// 已支付状态类
public class PaidState implements OrderState {
@Override
public void handle() {
System.out.println("当前订单状态:已支付");
// 处理已支付状态的逻辑
}
}
// 待发货状态类
public class ToBeShippedState implements OrderState {
@Override
public void handle() {
System.out.println("当前订单状态:待发货");
// 处理待发货状态的逻辑
}
}
// 已发货状态类
public class ShippedState implements OrderState {
@Override
public void handle() {
System.out.println("当前订单状态:已发货");
// 处理已发货状态的逻辑
}
}
然后,创建一个工厂类 OrderStateFactory
,用于动态创建订单状态对象。
在严格意义上这个工厂是一个不支持扩充的,但是在这里仅作为一个示例,如果想要真正达到动态创建还是需要用到工厂方法,这里只能算是一个简单工厂。
// 订单状态工厂类
public class OrderStateFactory {
public static OrderState createOrderState(String stateName) {
switch (stateName.toLowerCase()) {
case "pendingpayment":
return new PendingPaymentState();
case "paid":
return new PaidState();
case "tobeshipped":
return new ToBeShippedState();
case "shipped":
return new ShippedState();
default:
throw new IllegalArgumentException("Invalid state name");
}
}
}
接下来,我们可以使用上述的状态类和工厂类进行订单状态切换的实践:
public class Main {
public static void main(String[] args) {
Order order = new Order(); // 创建订单
// 设置待支付状态
order.setCurrentState(OrderStateFactory.createOrderState("PendingPayment"));
order.request();
// 支付订单,切换到已支付状态
order.setCurrentState(OrderStateFactory.createOrderState("Paid"));
order.request();
// 发货,切换到待发货状态
order.setCurrentState(OrderStateFactory.createOrderState("ToBeShipped"));
order.request();
// 完成发货,切换到已发货状态
order.setCurrentState(OrderStateFactory.createOrderState("Shipped"));
order.request();
}
}
通过工厂模式,我们可以根据状态名称动态地创建不同的订单状态对象,并将其设置为上下文类的当前状态。这样,如果要新增或修改订单状态,只需要修改工厂类的代码,而不需要修改客户端的代码。这增强了状态模式的灵活性和可扩展性。