2010-11-05 74 views
5

我正在尋找關於如何構建優雅解決方案的指導,以解決已成爲棘手問題的問題。雖然我使用Ruby(和Rails),但我認爲我的問題在很大程度上是一個架構問題,儘管我選擇的語言顯然對涉及庫等的建議有影響,所以語言仍然相關。涉及經常性支付和未來事件的難題架構問題

無論如何,簡而言之:我的應用程序包含代表會員的對象,屬於健身設施成員。會員資格包含一系列經常性付款。一些會員資格在任期結束時自動更新,而其他會員則不會。

因此,例如,您可能會有一個初始期限爲一年的成員資格,然後在此之後每月更新一次。在該應用程序中,創建此類會員資格會導致創建12次定期付款。當上個月到期時,會員也是如此。根據已完成的付款,每日cron任務負責導致成員資格到期。如果成員資格設置爲自動更新,則相同的cron任務將更新成員資格。

您也可能擁有沒有初始任期的會員資格,只需按月或按周運行即可。這些工作方式類似,減去最初的付款時間表。

到目前爲止這麼好。是什麼讓事情複雜化是額外的要求:

  • 管理員可以「凍結」成員(把它們保留),針對特定的持續時間,之後他們會自動激活(如代表的人誰去外出度假的設定的時間段)。我可以選擇立即凍結會員資格,並在稍後重新激活,或者我可以選擇通過設置將來的某個時間點的凍結日期以及重新激活日期來安排凍結(注意:總共有 a重新激活日期,這使事情變得更容易)。

  • 管理員可以立即取消會員資格,也可以通過設置將來取消會員資格。 (未來的取消尚未建立。)

  • 管理員可以退還會員資格,這就像是取消會員資格,除了任何過去的付款被退還。

是什麼讓這些難以處理的是對經常性支付的影響。當您凍結會員資格時,定期付款必須在凍結期間「延長」,以便代表凍結的時間段不被支付。這在概念和程序上都難以處理。例如,付款可能會延長到不同的時期(即每隔一週支付兩週會員資格的人的每次付款),並且取消日期可能在付款期限內的任何地方。

對於凍結,我採取了成員資格對象包含一些日期的方法,即「freeze_on」和「thaw_on」來處理凍結期。然而,客戶現在也想要取消未來,並且我注意到了凍結功能中的一些錯誤,這使我相信我需要重新考慮我的方法。

我正在考慮改變事情,以便將來的事件可以安排,但對應用程序的定期付款部分沒有影響。這個想法將排隊特定的事件。例如,通過在特定日期排隊凍結事件和在隨後的日期解凍事件(這兩個事件將從用戶的角度連接到單個「計劃凍結」)來實現將來的凍結。未來的取消將被類似地處理。

這種方法有一些好處,例如,如果你想取消未來的取消(這是我討論的那種令人討厭,棘手的東西),你可以簡單地從事件隊列中移除定期取消。

不過,我有嘮叨的感覺,我可能只是從煎鍋跳入火中。我想知道是否有人能夠就此問題向我提供一些指導。我可以研究這類問題的設計模式還是現有的架構原則?

還有一點需要注意的是,對於具有計劃條款(即不是按月自動更新)的會員的定期付款必須作爲可以編輯(時間移動,價格調整)的數據庫記錄存在,因此使用臨時就我所知,表達式(正如Martin Fowler所建議的)不適用於這個問題。我意識到,我提議的事件隊列解決方案不會向用戶顯示任何現有定期付款會發生的變化,但我認爲我可以忍受這一點。

不是的ScanLife條形碼,這是一個QR碼

多倫多,給我們你的創意人

編輯:爲了下面的兩個偉大的建議作出迴應(評論框不近讓這種詳細程度):

克里斯羅比森:

  1. 是的,凍結期可以是任意長度,儘管實際上我認爲它會少於兩週。但是任何解決方案都應該工作,不管時間的長短。

  2. 是的,更新日期改變 - 它被凍結的長度推進。所以如果凍結時間長達兩週,它會推遲兩週的付款。爲了使事情變得特別棘手,在一些企業中,付款只能在特定日期提取 - 例如,某些俱樂部僅在每個月的第1天和第15天處理付款。所以當日期被推動時,對於這些俱樂部來說,他們必須「快速」到某個特定的日期。

你能否更詳細地解釋了爲什麼這些規則影響的事件排隊,但不管理訂閱費的?

我對你的攤銷表概念很感興趣。這基本上就是我已經建立的 - 每月支付的會員年數爲12,每週創建爲52,並且每個會員都有與其相關的金額,稅金等,還有一個管理狀態機「待處理」,「已付款」,「失敗」和「退款」狀態。

我正在努力的部分是這個表如何響應事件。現在,如果您設置了凍結,則會立即通過更改付款日期來影響表格。在表格中間凍結,並推動付款。這聽起來很有效,但實際上它非常複雜且難以管理。您的攤銷表想法如何改善這種情況?

Arsen7:

這聽起來像我最初提出的事件隊列。對我來說,看起來很明顯,你之前曾使用過這樣的東西(我在處理日期對你的錯誤檢查印象深刻,這是一個好主意,我打算儘快實現),所以我希望你能解釋一下你的建議更詳細一點。

具體而言,我想知道您的概念如何處理我在原始問題中描述的經常性付款情況,以及我剛纔在Kris Robison的答案中留下的評論。如果我爲給定購買設置了定期付款的時間表,並且在付款過程中計劃了正確的凍結事件,則付款時間表會保持不變,直到凍結日期成爲當前日期凍結的時間將會被制定,並且付款會向前推進?

這可能是一種簡化應用程序的好方法,但我想知道用戶如何看待它。我如何向他們表明他們在計劃凍結時所看到的付款時間表不再是一個準確的時間表,而是一旦發生凍結就會改變?

+0

好吧,我剛編輯答案給出編輯問題的答案。 ;-)原諒我那麼長時間的延遲 - 我有一些相對繁忙的日子。 – Arsen7 2010-11-17 13:37:42

回答

3

應用銀行業務使用的方案是否可以接受?您每天處理所有帳戶操作一次?每個對象可能有一組(未來)操作,如凍結期間,每天對象都必須作出一個簡單的決定,例如:「我應該今天過期還是不過期?」

好的部分是,這樣的日常處理是非常簡單的編程。另外一個奇怪的更新規則(如果你想要他們)很容易設計:「它是星期五嗎?它是這個月的最後一個嗎?如果是的話,請將我標記爲更新,增加一些金額到需要的付款,或者做任何事情」。

每次詢問對象時,動態計算狀態將會非常昂貴(就計算能力而言)。如果您存儲當前的「帳戶」,則只需要進行更復雜的計算即可預測未來狀態。

認爲這是一個僞代碼:

def process(day) 
    raise "Already processed or missed a day" unless day == last_processed_day + 1 

    check_expiration day 
    check_frozen day 
    check_anything day 
    #... 

    self.last_processed_day = day 
    self.save! 
end 

迴應:

具體來說,我想知道你的概念將如何處理我在我原來的問題描述經常性支付情況,以及我剛纔在克里斯羅賓遜的回答中留下的評論。如果我爲給定購買設置了定期付款的時間表,並且在付款過程中計劃了正確的凍結事件,則付款時間表會保持不變,直到凍結日期成爲當前日期凍結的時間將會被制定,並且付款會向前推進?

這可能是一種簡化應用程序的好方法,但我想知道用戶如何看待它。我如何向他們表明他們在計劃凍結時所看到的付款時間表不再是一個準確的時間表,而是一旦發生凍結就會改變?

「日常處理」方案可幫助您爲需要複雜計算的問題提供快速響應。

你有三個「組」:當前狀態(經常問),歷史(幾乎不會改變,相對較少詢問)和未來。

您的日常處理過程不限於只更新「當前」狀態。如果某個事件計劃在處理日期,則該過程可能需要添加「歷史記錄」記錄。

如果你的用戶經常會問未來的問題(如你所說,他們會),「處理」也可能爲這些問題創建一種緩存。例如:查找(計算)下一個付款日期,並將其寫入助手錶(日程表)中。

您需要做的主要事情是決定用戶會問哪些問題,以及您是否能夠即時計算答案或者您需要準備好答案。

如果您詢問您目前的餘額,銀行(當然會有所不同),他們可能會在一天開始時給您答案。 「更好」的銀行會告訴你,早上你有X $,但現在也有Y $等待會計。

因此,如果您將凍結記錄放入事件隊列中,您可以調用一個方法,該方法將一次更新計劃。日常處理程序中將會或可能會調用相同的程序(或非常類似的程序)。

+0

我編輯了我的問題以迴應您的回答(在評論框中沒有足夠的空間)。 – adriandz 2010-11-07 13:15:26

+0

只是想很快爲此感謝你 - 在過去的幾周裏,我終於深入瞭解並開發了一個解決方案,並且您的意見非常有幫助。你和克里斯之間既不「正確」,但你們都很有幫助,我感謝你花時間回答這個問題。克里斯,如果你讀了這篇文章,我沒有選擇你的答案,只是因爲它看起來不像你使用網站了! – adriandz 2011-07-07 18:54:30

1

幾個問題浮現在腦海中:

  1. 凍結可對於不到一個月的時間段?
  2. 如果是這樣,更新日期是否改變?或者月度付款如何申請該部分月份?

這些影響您的事件排隊系統如何工作,但最終不會改變訂閱付款的管理。

解決訂閱問題的一種方法是創建訂閱付款的攤銷表。如果他們每月支付一年的費用,則會在表格中排隊等待12次付款。每週的客戶可能在同一年的表中有52筆付款。每次更新日期出現時,在檢查凍結是否到位後,應用下一次付款。

攤銷表會跟蹤哪些付款已經完成。如果帳戶取消,未付行將退還。如果帳戶根據您的事件隊列凍結,則不會應用任何付款,並且該表在該帳戶解凍之前保持靜態。

回覆

這聽起來像你有安全的攤銷表更新日期的概念。我更多地使用分期付款表作爲隊列,並保留訂閱的下一個更新日期。

如果更新日期與攤銷表是固有的,那麼是的,隨着事情的發展進行更改將變得很複雜。但是,續訂日期只應影響您檢查是否應用其他付款的日期。

如果您在保留訂購期間保留部分付款,並且如果持有可能持續了未指定的時間段,則在攤銷表上持有持續時間值可讓您將部分付款重新插入「信用」狀態的持續時間等於付款剩餘時間。通過這種方式,當賬戶解凍時,首先應用部分抵免,然後從剩餘持續時間計算下一個續約日期。

使用某種形式的有序列表來保留此時的付款訂單。出於客戶服務原因,如果有人想要插入續展期的信用價值,它也派上用場。

+0

我編輯了我的問題以迴應您的回答(在評論框中沒有足夠的空間)。 – adriandz 2010-11-07 13:16:56