USSD(状态机)应用算法

时间:2013-12-22 05:44:04

标签: php algorithm state-machine ussd

我用PHP创建了一个USSD应用程序,因为USSD请求是唯一的(每个选择的新请求)我需要一种方法来跟踪它们,跟踪我需要一种方法来存储应用程序的流程,在我的USSD应用程序有静态菜单和动态菜单(从数据库中检索),我的问题是,我已经创建了包含大量if,else和switch语句的应用程序,而且更新菜单项真的很难。那么有谁能建议我创建这个USSD应用程序的好算法?我的意思是解决问题的有效方法,我需要一种能够根据客户端请求添加和删除菜单的方法,当我这样做时,我的代码不应该破坏。任何人都可以帮我吗?

-Thanks&此致

PS:我已阅读thisthis,但实际上并没有回答我的问题。

2 个答案:

答案 0 :(得分:3)

使用USSD的最佳方法是使每个command成为一个单独的类。这样,您就可以工作,调试和维护大型USSD应用程序

示例

$ussd = new USSDMessage(); // USSD Class 

$main = new Command("menu"); // Starting Command 

// Register multiple command 
$main->register(new Command("help"));
$main->register(new Command("account"));
$main->register(new Command("transfer"));
$main->register( new Recharge("reacharge"));

$main->run($ussd); // Run Request 

基本班级结构

// Class To receve message from USSD
class USSDMessage {
    function next();
    function saveSession();
}

// Basic Command  Class 
class Command {
    private $name;
    private $cmd = array();

    function __construct($name) {
        $this->name = $name;
    }

    function register(Command $menu) {
        $this->cmd[$menu->getName] = $menu;
    }

    function run(USSDMessage $ussd) {
        $key = $ussd->next(); // get next inpur from ussd

        if (isset($this->cmd[$key])){
            $ussd->run($ussd);
        }
    }
}

// Recharge Command Example 
class Recharge extends Command {

    function run(USSDMessage $ussd) {
        $key = $ussd->next();

        switch ($key){
            case "1":
                // Proccess card recharge
                // Do Somthing 
                $ussd->saveSession(); // End Session 
                break;
            case "2":
                // Process direct deposit
                // Do Somthing
                $ussd->saveSession(); // End Session
                break;
            default:
                // Format Not supported
                // Do Somthing
                $ussd->saveSession(); // End Session
                break;
        }
    }
}

答案 1 :(得分:2)

根据我从OP提出的问题,这里有一些提示:

此问题与树遍历有关。菜单的每个状态都将存储在树的一个节点上。

如果您对后缀树/特里read here一无所知。这个想法很简单,因为用户输入的选项有限:0,1,2,3,4,5,6 ... 9,#,*,我们可以代表一棵树中的所有状态。

树的每个节点都是这样的:

Node{        
    Node [] next = new Node[12];//All options from 0 to *
    Menu menu;
}

因此,我们可以通过使用和遍历树从根到叶来轻松定位和存储所有状态,而不是if和switch。要引用所有状态,我们只需要存储一个变量:Node root

例如,如果我们有一系列动作#111#。 (假设#在索引10处且*在索引11处)我们将始终从root开始 - >转到索引10->的节点;转到索引1处的Node ...最后,返回菜单。

伪代码:

Menu traverse(String input){
    Node cur = root;
    for(int index in input){
        cur = cur.next[index];
    }
    return cur.menu;
}

对于删除状态/分支,只需从根遍历到该叶子,并用next替换父null数组中的叶节点。

注意 :如果将所有菜单存储在数组Menu[]menu中,并且对于每个节点,您可以更轻松地管理菜单列表,而不是返回在菜单中,您将返回一个整数,表示数组menu中所需菜单的索引。