第12 屆iT邦幫忙鐵人賽系列文章 (Day12)
這篇要來緩一下,做第一次的重構,寫到現在會發現 LineBotApp.cs 這個 class開始複雜了,程式碼越來越長,在OnMessageAsync.OnPostbackAsync 開始有相同的 Intent 重複定義
我們把取得 Intent 封裝成一個工廠
IIntentFactory.cs 定義一個工廠介面
public interface IIntentFactory
{
IReplyIntent GetIntent(string intentName, string userId);
}
IntentFactory.cs 實作這個介面
public class IntentFactory : IIntentFactory
{
private readonly LineReplyMessageUtility lineMessageUtility;
private readonly LineProfileUtility lineProfileUtility;
public IntentFactory(LineReplyMessageUtility _lineMessageUtility, LineProfileUtility _lineProfileUtility)
{
lineMessageUtility = _lineMessageUtility;
lineProfileUtility = _lineProfileUtility;
}
public IReplyIntent GetIntent(string intentName, string userId)
{
var intents = new Dictionary<string, IReplyIntent>()
{
{ "Welcome" , new Welcome(lineMessageUtility,lineProfileUtility,userId)},
{ "電子喜帖" , new WeddingInvitationFromImage(lineMessageUtility,lineProfileUtility)},
{ "電子喜帖(FlexMsg)" , new WeddingInvitation(lineMessageUtility,lineProfileUtility)},
{ "前導影片" , new WeddingTrailer(lineMessageUtility,lineProfileUtility)},
{ "婚宴地點" , new WeddingLocation(lineMessageUtility,lineProfileUtility)},
{ "婚紗輪播" , new PhotoCarousel(lineMessageUtility,lineProfileUtility)},
{ "交通資訊" , new Directions(lineMessageUtility,lineProfileUtility)},
{ "從高鐵" , new DefaultIntent(lineMessageUtility,lineProfileUtility,"至 北門站 搭乘松山新店線至 南京復興站 步行7分鐘")},
{ "從捷運" , new DefaultIntent(lineMessageUtility,lineProfileUtility,"捷運台北小巨蛋站6分鐘/南京復興站只需7分鐘")},
{ "從機場" , new DefaultIntent(lineMessageUtility,lineProfileUtility,"酒店距離松山國際機場僅 5 分鐘車程")},
{ "停車資訊" , new DefaultIntent(lineMessageUtility,lineProfileUtility,"酒店的停車場為室內停車場,位於B5及B6")},
{ "開車提醒" , new DefaultIntent(lineMessageUtility,lineProfileUtility,"? 當天有紅酒享用,切記開車不喝酒,快快樂樂平平安安的回家~ ?")},
{ "Default" ,new DefaultIntent(lineMessageUtility,lineProfileUtility)},
};
return intents.ContainsKey(intentName) ? intents[intentName] : intents["Default"];
}
}
LinebotApp.cs
注入IIntentFactory,原本的 lineMessageUtility.lineProfileUtility 職責改由工廠裡面使用,LineBotApp 不再處理回覆的職責,這邊也不需要注入了
記得要在 Startup.cs 注入
LineBotApp.cs 重構後
這樣就乾淨多了,也不用相同的 intent 重複寫了兩次,重構到這篇,覺得還夠用,之後實作開始複雜我們再來繼續重構
protected virtual async Task OnMessageAsync(Event ev)
{
if (ev.message.Type.Equals(LineMessageType.text))
{
var intent = intentFactory.GetIntent(ev.message.Text, ev.source.userId);
await intent.ReplyAsync(ev.replyToken);
}
}
protected virtual async Task OnFollowAsync(Event ev)
{
var intent = intentFactory.GetIntent(intentName: "Welcome", ev.source.userId);
await intent.ReplyAsync(ev.replyToken);
}
protected virtual async Task OnUnfollowAsync(Event ev)
{
// 可以記錄誰封鎖了這個Bot
await Task.CompletedTask;
}
protected virtual async Task OnUnPostbackAsync(Event ev)
{
var intent = intentFactory.GetIntent(ev.postback.data, ev.source.userId);
await intent.ReplyAsync(ev.replyToken);
}
本篇文章同步發佈於我的 Medium 如果這篇文章對你有幫助,就大力追蹤和拍手鼓掌下去吧 !!