![[Bot Framework V4][10]在Dialog裡面做Branching以及Looping把不同目的更加模組化.jpg](/posts/2018/11/2018-11-13-bot-framework-v4-10-use-branching-and-looping-in-dialogset-to-modularise-logic/63169a8f-2f10-48f8-83e2-e42d57488a1b.jpg)
在上一篇([09]使用waterfall建立表單式填寫)介紹了使用watfall
的方式達到建立一個表單式搜集的chatbot。
裡面爲了簡化把取得姓名的部分暫時拿掉了,但是在實務上不同邏輯的dialog可能會存在,那怎麽辦呢?
這篇將介紹透過Dialog來做Branching以及Looping。
什麽是Branching和Looping
Branching就和名稱一樣的意思,分叉出去。
舉例來説,假設我的waterfall啓動的時候,因爲收到了什麽訊息這個時候啓動另外一個waterfall, 這個時候除非另外一個(剛啓動那個)waterfall結束,要不然不會繼續往原本的繼續執行下去。
這個就是所謂的Branching,先分叉出去,然後執行完了在分叉回來。
Branching是透過呼叫BeginDialogAsync
達到。
Looping和字面上面的意思也一樣,當waterfall執行到最後一步的時候,不結束,重新又new一個同樣的waterfall,這樣就延續執行下去。
換而言之,就達到了一直loop。
Looping是透過呼叫ReplaceDialogAsync
來達到。
加入Branching和Looping的概念到目前的範例
對到目前的範例來説:
- 需要有branching分支出去執行取得姓名以及取得訂房這兩個flow
- 需要有loop,這樣整個waterfall永遠不會結束
因此整個流程概念如下:

上圖有幾個重要的部分:
- 藍色的框框代表3個大flow
有3個大藍色的框框:
- root - 這個是整個流程的起始點。root裡面有個echo - 當另外兩個branching條件不符合的時候,echo會觸發。
- askNameWaterfall - 當使用者沒有輸入過姓名的時候,將透過branching的方式觸發這段的waterfall
- bookRoom - 當使用者輸入
訂房
的時候,將透過branching的方式觸發
- 橘紅色的綫
-
代表是branching的部分,從root這個waterfall切換到另外兩個branching。
這邊
echo
有點特別,因爲他不屬於branching因此屬於root的一部分 - 綠色的綫
- 代表是looping的部分。當其他watefall結束的時候,都會回到root waterfall。
修改現行的程式碼
上面有了概念之後,來看看如何調整現行的程式碼來達到使用branching以及looping。
整個修改會分爲幾個部分:
- 建立一個
HotelDialogSet
- 完成詢問姓名的waterfall
- 完成訂房的waterfall
- 完成root waterfall
- 整合到bot呼叫HotelDialogSet
建立一個HotelDialogSet
首先建立出一個class叫做HotelDialogSet
,然後讓這個class繼承DialogSet
,透過這個方式讓邏輯整合到這個class就好。
由於之後會使用到Accessor來取得儲存的值,因此會用建構子傳入來,最後整個class:
完成詢問姓名的waterfall
首先來完成詢問姓名的waterfall,整個的邏輯和之前篇幅看到的一樣,定義出一個WaterfallDialog,用來取得使用者姓名:
上面程式碼應該不太需要介紹,定義了了一個Waterfall,裡面有兩個step用來取得姓名以及儲存在Accessor。
完成訂房的waterfall
看過了上面詢問名字的部分,相信對於訂房的做法也就很清楚了 - 一樣是建立一個waterfall,裡面定義出完成訂房需要的step。
首先是在建構子的時候建立出waterfall的step:
再來就是看看每一個step的實際動作:
完成root waterfall
剩下最後一個waterfall了,也就是所有的起點,root
的waterfall。
一樣就是先在建構子定義出這個waterfall的step:
再來看看實際step裡面執行的内容:
這邊最重要的就是ProcessRootAsync
以及LoopRootAsync
。
在ProcessRootAsync
裡面,透過呼叫BeginDialogAsync
來做到branching - 依照輸入内容不同branch到不同的waterfall。
然後在LoopRootAsunc
裡面呼叫ReplaceDialogAsync
來做到looping。
整合到bot呼叫HotelDialogSet
最後切換到EchoWithCounterBot
來設定把整個流程啓動起來。
首先把HotelDialogSet
在建構子的時候建立出來:
最後要把整個啓動起來:
EchoWithCounterBot
裡面刪除原本code的部分處理 - 如果在處理上有遇到問題,歡迎參考範例程式碼。
測試結果
首先是看取得姓名的部分:

再來使用關鍵字訂房
:

最後如果輸入其他任何内容,都變成echo模式:

結語
這篇透過建立出一個自己的DialogSet并且透過branching以及looping的方式讓整個組合運作起來。
透過邏輯整合到自己的DialogSet,在呼叫端(EchoWithCounterBot
)變得非常的乾净,并且邏輯也分別出去了。
可是還是產生了別的問題,現在所有邏輯都卡在了DialogSet裡面,尤其是2個waterfall明明是不同的東西難道不能夠抽出去嗎?可不可以抽到一個獨立module然後需要的時候整合使用呢?
這就是composite dialogs的作用,下一篇再來介紹。