我正在使用php
创建一个 USSD 页面。我以前做过这个,这是一项相当受时间限制的黑客工作。基本上是一个带有switch语句的大文件,其中包含手机用户可能处于的所有可能状态(然后将其保存在数据库中并在下一个USSD请求时检索)——一种状态机。
这一次我有更多的时间,想用更专业的东西。是否有任何设计模式或最佳实践可用于这种场景?
我正在使用php
创建一个 USSD 页面。我以前做过这个,这是一项相当受时间限制的黑客工作。基本上是一个带有switch语句的大文件,其中包含手机用户可能处于的所有可能状态(然后将其保存在数据库中并在下一个USSD请求时检索)——一种状态机。
这一次我有更多的时间,想用更专业的东西。是否有任何设计模式或最佳实践可用于这种场景?
我也曾与这个问题作斗争。我的方法是使用一个树,其中每个 ussd 状态都是一个节点。让我说明我能做到的最好的方式
interface Node {
render(),
process(input)
}
节点分为选择节点和输入节点。
选择节点只是向用户提供可以从中选择的选项,然后将用户引至其子节点或显示错误消息
class Selection extends Node {
Node[] children;
string title;
render() {
// create a ussd menu here appending title to
// menu items based on this.children
}
process(input) {
// get input and select from children node
// call its render method
}
}
输入节点收集来自用户的实际输入(如姓名、凭证号等)并执行查询数据库或调用远程 API 等处理,然后向用户呈现响应。
class Input extends Node {
string title;
string instruction;
Handler handler;
render() {
// show title and/or instruction to user
}
process(input) {
// validate input and then pass to this.handler
}
}
为了进一步解耦逻辑,我添加了一个处理程序接口,每个输入节点都需要一个处理程序。所有的处理逻辑都驻留在 Handler 中
interface Handler {
handle()
}
现在,您创建了一个解析器类来处理 ussd 会话信息和所有 http 内容(如果您通过 http 接收 ussd 请求)。解析器还根据用户输入横穿树以收集负责的节点,然后调用它的渲染或处理方法。你的树看起来像这样
new Selection('Main Menu (title)', [
new Selection('My account', [...]),
new Input('Recharge', 'Enter voucher number', new RechargeHandler())
]);
这是特定于我的用例的有限解决方案,我相信它可以扩展以适应其他情况。我想听听其他人是如何解决这个问题的