阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

状态

24次阅读
没有评论

共计 1618 个字符,预计需要花费 5 分钟才能阅读完成。

允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。

状态模式(State)经常用在带有状态的对象中。

什么是状态?我们以 QQ 聊天为例,一个用户的 QQ 有几种状态:

  • 离线状态(尚未登录);
  • 正在登录状态;
  • 在线状态;
  • 忙状态(暂时离开)。

如何表示状态?我们定义一个 enum 就可以表示不同的状态。但不同的状态需要对应不同的行为,比如收到消息时:

if (state == ONLINE) {// 闪烁图标
} else if (state == BUSY) {reply("现在忙,稍后回复");
} else if ...

状态模式的目的是为了把上述一大串 if...else... 的逻辑给分拆到不同的状态类中,使得将来增加状态比较容易。

例如,我们设计一个聊天机器人,它有两个状态:

  • 未连线;
  • 已连线。

对于未连线状态,我们收到消息也不回复:

public class DisconnectedState implements State {public String init() {return "Bye!";
    }

    public String reply(String input) {return "";
    }
}

对于已连线状态,我们回应收到的消息:

public class ConnectedState implements State {public String init() {return "Hello, I'm Bob.";
    }

    public String reply(String input) {if (input.endsWith("?")) {return "Yes." + input.substring(0, input.length() - 1) + "!";
        }
        if (input.endsWith(".")) {return input.substring(0, input.length() - 1) + "!";
        }
        return input.substring(0, input.length() - 1) + "?";
    }
}

状态模式的关键设计思想在于状态切换,我们引入一个 BotContext 完成状态切换:

public class BotContext {private State state = new DisconnectedState();

	public String chat(String input) {if ("hello".equalsIgnoreCase(input)) {// 收到 hello 切换到在线状态:
			state = new ConnectedState();
			return state.init();} else if ("bye".equalsIgnoreCase(input)) {
            /  收到 bye 切换到离线状态:
			state = new DisconnectedState();
			return state.init();}
		return state.reply(input);
	}
}

这样,一个价值千万的 AI 聊天机器人就诞生了:

Scanner scanner = new Scanner(System.in);
BotContext bot = new BotContext();
for (;;) {System.out.print(">");
    String input = scanner.nextLine();
    String output = bot.chat(input);
    System.out.println(output.isEmpty() ? "(no reply)" : "<" + output);
}

试试效果:

> hello
< Hello, I'm Bob.
> Nice to meet you.
< Nice to meet you!
> Today is cold?
< Yes. Today is cold!
> bye
< Bye!

练习

新增 BusyState 状态表示忙碌。

下载练习

小结

状态模式的设计思想是把不同状态的逻辑分离到不同的状态类中,从而使得增加新状态更容易;

状态模式的实现关键在于状态转换。简单的状态转换可以直接由调用方指定,复杂的状态转换可以在内部根据条件触发完成。

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2024-08-05发表,共计1618字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中