2010-11-05 8 views
5

मैं एक कांटेदार समस्या का थोड़ा सा बनने के लिए एक सुरुचिपूर्ण समाधान कैसे वास्तुकार करने के लिए मार्गदर्शन की तलाश में हूं। हालांकि मैं रूबी (और रेल) ​​का उपयोग कर रहा हूं, मुझे लगता है कि मेरी समस्या काफी हद तक एक वास्तुशिल्प है, हालांकि भाषा की मेरी पसंद स्पष्ट रूप से पुस्तकालयों आदि से जुड़े सुझावों के संदर्भ में प्रभाव डालती है, इसलिए भाषा प्रासंगिक बनी हुई है।आवर्ती भुगतान और भविष्य की घटनाओं को शामिल करने वाली कठिन वास्तुकला की समस्या

वैसे भी, संक्षेप में: मेरे आवेदन में सदस्यता का प्रतिनिधित्व करने वाली वस्तुएं हैं, जो फिटनेस सुविधाओं के सदस्य हैं। सदस्यता में पुनरावर्ती भुगतान की एक श्रृंखला होती है। कुछ सदस्यता स्वचालित रूप से अपने कार्यकाल के अंत में नवीनीकृत होती है, जबकि अन्य नहीं करते हैं।

तो उदाहरण के लिए, आपके पास एक सदस्यता हो सकती है जो एक वर्ष की प्रारंभिक अवधि के लिए हो, और उसके बाद महीने-दर-महीने नवीनीकृत हो। आवेदन में, इस तरह की सदस्यता बनाने के लिए 12 पुनरावर्ती भुगतान किए जाने का कारण बनता है। जब अंतिम महीने समाप्त हो जाता है, तो सदस्यता भी होती है। पूर्ण भुगतान के आधार पर सदस्यता समाप्त होने के कारण दैनिक क्रॉन कार्य जिम्मेदार होता है। यदि सदस्यता स्वचालित रूप से नवीनीकृत करने के लिए सेट है, तो उसी क्रॉन कार्य सदस्यता को नवीनीकृत कर देगा।

आपके पास ऐसी सदस्यता भी हो सकती है जिनके पास प्रारंभिक अवधि नहीं है और केवल महीने-दर-महीने या सप्ताह-दर-सप्ताह चलती है। ये काम समान तरीके से प्रारंभिक भुगतान शेड्यूलिंग से कम है।

अभी तक इतना अच्छा है। क्या बनाता है जटिल चीजों को अतिरिक्त आवश्यकताएँ हैं:

  • प्रशासकों की सदस्यता (पकड़ पर डाल), विशिष्ट अवधि के लिए, जिसके बाद वे स्वचालित रूप से (जैसे लोग हैं, जो एक के लिए छुट्टी पर चले जाओ प्रतिनिधित्व करने के लिए पुन: सक्रिय "फ्रीज" कर सकते हैं समय की निर्धारित अवधि)। मैं अभी सदस्यता को जमा करना चुन सकता हूं और इसे बाद में पुनः सक्रिय कर सकता हूं, या मैं भविष्य में किसी बिंदु पर फ्रीज तिथि सेट करके फ्रीज तिथि निर्धारित कर सकता हूं, साथ ही पुन: सक्रियण तिथि (नोट: हमेशा ए पुनर्सक्रियण तिथि, जो चीजों को थोड़ा आसान बनाता है)।

  • व्यवस्थापक अभी भी सदस्यता रद्द कर सकते हैं, या तो भविष्य में होने वाली रद्दीकरण को सेट कर सकते हैं। (भविष्य रद्दीकरण अभी तक नहीं बनाए गए हैं।)

  • प्रशासक सदस्यता रद्द कर सकते हैं, जो किसी भी पिछले भुगतान को छोड़कर रद्दीकरण की तरह है।

आवर्ती भुगतान पर असर इन मुश्किलों से निपटने में क्या मुश्किल बनाता है। जब आप सदस्यता जमा करते हैं, आवर्ती भुगतान को फ्रीज अवधि के आसपास "बाहर निकालना" चाहिए, ताकि फ्रीज का प्रतिनिधित्व करने वाले समय की अवधि का भुगतान न किया जाए। यह दोनों अवधारणात्मक और प्रोग्रामेटिक रूप से संभालना मुश्किल है। भुगतान, उदाहरण के लिए, विभिन्न अवधि के लिए बढ़ाया जा सकता है (यानी प्रत्येक भुगतान जो किसी अन्य सप्ताह के लिए सदस्यता के दो सप्ताह के लिए भुगतान करता है), और रद्दीकरण की तारीख भुगतान कवर अवधि के भीतर कहीं भी हो सकती है।

फ्रीज के लिए, मैंने उस दृष्टिकोण को लिया है जहां सदस्यता वस्तु में कुछ तारीखें हैं, अर्थात् फ्रीज अवधि को संभालने के लिए "फ्रीज_ऑन" और "thaw_on"। हालांकि, ग्राहक अब भविष्य में रद्दीकरण भी चाहता है, और मैंने ठंडे कार्यक्षमता के साथ कुछ कीड़े देखी हैं, जो मुझे विश्वास दिलाती है कि मुझे अपने दृष्टिकोण पर पुनर्विचार करने की आवश्यकता है।

मैं चीजों को बदलने पर विचार कर रहा हूं ताकि भविष्य की घटनाओं को निर्धारित किया जा सके लेकिन आवेदन के पुनरावर्ती भुगतान हिस्से पर कोई प्रभाव न हो। विचार विशेष घटनाओं को कतार में रखना होगा।उदाहरण के लिए, भविष्य में एक फ्रीज किसी विशेष तिथि पर फ्रीज ईवेंट को कतारबद्ध करके, और बाद की तारीख पर एक थॉव ईवेंट (इन दो घटनाओं को उपयोगकर्ता के परिप्रेक्ष्य से एक "अनुसूचित फ्रीज" में जोड़ा जाएगा) द्वारा पूरा किया जाएगा। भविष्य में रद्दीकरण को समान रूप से संभाला जाएगा।

इस दृष्टिकोण के कुछ फायदे हैं, उदाहरण के लिए, यदि आप भविष्य में रद्दीकरण रद्द करना चाहते हैं (यह ऐसी परेशानियों, मुश्किल चीजें हैं जिनके बारे में मैं बात कर रहा हूं), तो आप ईवेंट कतार से निर्धारित रद्दीकरण को हटा सकते हैं।

हालांकि, मुझे नाराज लग रहा है कि मैं बस फ्राइंग पैन से आग में कूद सकता हूं। मैं सोच रहा हूं कि कोई मुझे इस मुद्दे पर कुछ मार्गदर्शन प्रदान कर सकता है। क्या इस तरह की समस्या के लिए डिजाइन पैटर्न या मौजूदा वास्तुशिल्प सिद्धांत हैं जिनकी मैं जांच कर सकता हूं?

नोट करने के लिए एक अतिरिक्त बात यह है कि निर्धारित शर्तों के साथ सदस्यता के लिए आवर्ती भुगतान (यानी महीने-दर-महीने स्वचालित रूप से नवीकरण नहीं) डेटाबेस रिकॉर्ड के रूप में मौजूद होना चाहिए जिसे संपादित किया जा सकता है (समय में स्थानांतरित किया गया है, मूल्य समायोजित किया गया है), इसलिए अस्थायी का उपयोग करना अभिव्यक्ति (मार्टिन फाउलर के सुझाव के अनुसार) इस समस्या के लिए उपयुक्त नहीं है, जहां तक ​​मुझे पता है। मुझे एहसास है कि किसी इवेंट कतार का मेरा प्रस्तावित समाधान उपयोगकर्ता को किसी मौजूदा आवर्ती भुगतान के साथ होने वाले परिवर्तनों को प्रदर्शित नहीं करेगा, लेकिन मुझे लगता है कि मैं इसके साथ रह सकता हूं। नीचे दो महान सुझाव के लिए प्रतिक्रिया करने के लिए (टिप्पणी बक्से लगभग अनुमति नहीं देते:

नहीं एक ScanLife बार कोड है, यह एक QR कोड

टोरंटो, हमें अपने रचनात्मक लोगों

संपादित देना है विवरण के स्तर):

क्रिस Robison:

  1. हां, फ्रीज अवधि मनमाना लंबाई हो सकती है, हालांकि अभ्यास में मुझे लगता है कि यह दो सप्ताह से कम होने के लिए दुर्लभ होगा। लेकिन किसी भी समाधान को अवधि की लंबाई के बावजूद काम करना चाहिए।

  2. हां, नवीकरण तिथि बदलती है - इसे फ्रीज की लंबाई से आगे बढ़ाया जाता है। तो यदि फ्रीज दो सप्ताह लंबा है, तो यह भुगतान को दो सप्ताह तक आगे बढ़ा देता है। चीजों को विशेष रूप से मुश्किल बनाने के लिए, कुछ व्यवसायों में, भुगतान केवल विशिष्ट तिथियों पर वापस ले लिया जा सकता है - उदाहरण के लिए, कुछ क्लब केवल प्रत्येक महीने के पहले और 15 वें स्थान पर भुगतान करते हैं। इसलिए जब इन क्लबों के लिए तारीखों को धक्का दिया जाता है, तो उन्हें किसी विशेष तारीख को "स्नैप" करना पड़ता है।

क्या आप अधिक विस्तार से समझा सकते हैं कि ये नियम ईवेंट कतार को क्यों प्रभावित करते हैं लेकिन सदस्यता भुगतान का प्रबंधन नहीं करते हैं?

मुझे आपकी परिशोधन तालिका अवधारणा में रूचि है। यह मूल रूप से वही है जो मैंने पहले ही बनाया है - मासिक भुगतान के साथ एक साल की सदस्यता 12 बनाता है, साप्ताहिक रूप से यह 52 बनाता है - और इनमें से प्रत्येक के पास एक राज्य मशीन के साथ जुड़े राशि, कर, आदि हैं। "लंबित", "भुगतान", "असफल", और "धनवापसी" राज्य।

जिस भाग में मैं संघर्ष कर रहा हूं वह यह है कि यह तालिका घटनाओं का जवाब कैसे देती है। अभी, यदि आप एक फ्रीज सेट करते हैं, तो यह भुगतान की तिथियों को बदलकर तुरंत तालिका को प्रभावित करता है। तालिका के बीच में फ्रीज सेट करें, और यह आगे भुगतान को धक्का देता है। यह प्रभावी लगता है, लेकिन यह वास्तव में काफी जटिल और प्रबंधन करने में मुश्किल है। आपकी परिशोधन तालिका विचार इस स्थिति में कैसे सुधार करेगा?

Arsen7:

इस घटना कतार मैं मूल रूप से प्रस्तावित की तरह लगता है। मुझे यह स्पष्ट लगता है कि आपने पहले इस तरह की चीजों के साथ काम किया है (मैं प्रसंस्करण तिथि पर आपकी त्रुटि जांच से प्रभावित था, यह एक अच्छा विचार है और एक जिसे मैं एएसएपी लागू करना चाहता हूं) इसलिए मुझे आशा है कि आप समझा सकते हैं थोड़ा सा विस्तार में आपका सुझाव।

विशेष रूप से, मैं सोच रहा हूं कि आपकी अवधारणा मेरे मूल प्रश्न में वर्णित आवर्ती भुगतान स्थिति से कैसे निपटती है, और टिप्पणी में मैंने क्रिस रोबिसन के उत्तर पर अभी छोड़ा था। यदि मैंने किसी दिए गए खरीद के लिए पुनरावर्ती भुगतान का शेड्यूल स्थापित किया है, और भुगतान के बीच में फ्रीज इवेंट निर्धारित किया गया है, तो भुगतान की अवधि अपरिवर्तित बनी रहेगी जब तक कि फ्रीज की तारीख वर्तमान तिथि बन जाए, जिस पर समय फ्रीज स्थापित किया जाएगा और भुगतान आगे बढ़ेगा?

यह मेरे आवेदन को सरल बनाने के लिए शायद एक शानदार तरीका है, लेकिन मुझे आश्चर्य है कि उपयोगकर्ता इसे कैसे समझेंगे। मैं उन्हें कैसे इंगित करूंगा कि जब फ्रीज निर्धारित किया गया था, तो वे भुगतान का शेड्यूल अब सटीक अनुसूची नहीं कर रहे हैं, लेकिन फ्रीज होने के बाद बदल जाएगा?

+0

ठीक है, मैंने अभी संपादित किए गए प्रश्न का उत्तर देने के लिए उत्तर संपादित किया है। ;-) मुझे लंबे समय तक देरी क्षमा करें - मेरे पास कुछ अपेक्षाकृत व्यस्त दिन थे। – Arsen7

उत्तर

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 

प्रतिक्रिया:

विशेष रूप से, मैं सोच रहा हूँ कि कैसे अपनी अवधारणा आवर्ती भुगतान स्थिति मैं अपने मूल प्रश्न में वर्णित किया है के साथ सौदा होगा , और टिप्पणी में कि मैंने क्रिस रोबिसन के जवाब पर अभी छोड़ा था। यदि मैंने किसी दिए गए खरीद के लिए पुनरावर्ती भुगतान का शेड्यूल स्थापित किया है, और भुगतान के बीच में फ्रीज इवेंट निर्धारित किया गया है, तो भुगतान की अवधि अपरिवर्तित बनी रहेगी जब तक कि फ्रीज की तारीख वर्तमान तिथि बन जाए, जिस पर समय फ्रीज स्थापित किया जाएगा और भुगतान आगे बढ़ेगा?

यह मेरे आवेदन को सरल बनाने के लिए शायद एक शानदार तरीका है, लेकिन मुझे आश्चर्य है कि उपयोगकर्ता इसे कैसे समझेंगे। मैं उन्हें कैसे इंगित करूंगा कि जब फ्रीज निर्धारित किया गया था, तो वे भुगतान का शेड्यूल अब सटीक अनुसूची नहीं कर रहे हैं, लेकिन फ्रीज होने के बाद बदल जाएगा?

"दैनिक प्रसंस्करण" योजना आपको जटिल गणना की आवश्यकता वाले प्रश्नों के त्वरित प्रतिक्रिया प्रदान करने में सहायता करती है।

आपके पास तीन "समूह" हैं: वर्तमान स्थिति (अक्सर पूछे जाने वाले), इतिहास (लगभग कभी नहीं बदलता, अपेक्षाकृत दुर्लभ रूप से पूछा जाता है), और भविष्य।

आपकी दैनिक प्रसंस्करण प्रक्रिया केवल "वर्तमान" स्थिति को अपडेट करने के लिए बाध्य नहीं है। यदि संसाधित दिन के लिए कुछ कार्यक्रम निर्धारित किया गया है, तो प्रक्रिया को शायद "इतिहास" रिकॉर्ड जोड़ने की आवश्यकता है।

यदि आपके उपयोगकर्ता अक्सर भविष्य के बारे में प्रश्न पूछेंगे (और जैसा कि आपने कहा था, वे करेंगे), "प्रसंस्करण" इन प्रश्नों के लिए एक प्रकार का कैश भी बना सकता है। उदाहरण के लिए: अगली भुगतान तिथि ढूंढें (गणना करें), और इसे एक सहायक तालिका (एक शेड्यूल) में लिखें।

मुख्य बात यह है कि आपको यह तय करना है कि उपयोगकर्ताओं द्वारा कौन से प्रश्न पूछे जाएंगे, और क्या आप उड़ान भरने के जवाबों की गणना करने में सक्षम हैं या आपको उत्तर तैयार करने की आवश्यकता है।

यदि आप अपनी वर्तमान शेष राशि के बारे में पूछते हैं तो यह एक बैंक में (यह भिन्न होता है), वे आपको वह उत्तर दे सकते हैं जो दिन की शुरुआत में सच था। "बेहतर" बैंक आपको बताएंगे कि सुबह में आपके पास एक्स $ था, लेकिन अब लेखा के लिए वाई $ इंतजार भी कर रहे हैं।

तो, यदि आप ईवेंट कतार में फ्रीज रिकॉर्ड डालते हैं, तो आप एक विधि कॉल कर सकते हैं, जो एक बार में शेड्यूल अपडेट करेगा। एक ही प्रक्रिया (या एक बहुत ही समान) दैनिक प्रसंस्करण दिनचर्या में या कहा जा सकता है।

+0

मैंने आपके प्रश्न का जवाब देने के लिए अपना प्रश्न संपादित किया है (टिप्पणी बॉक्स में पर्याप्त कमरा नहीं)। – adriandz

+0

बस इसके लिए आपको जल्द से जल्द धन्यवाद देना चाहता था - पिछले कुछ हफ्तों में मैंने आखिरकार इसमें प्रवेश किया और एक समाधान विकसित किया, और आपकी टिप्पणियां काफी उपयोगी थीं। आप और क्रिस के बीच न तो "सही" हैं लेकिन आप दोनों सहायक थे, और मैं आपको जवाब देने के लिए समय लेने की सराहना करता हूं। क्रिस, अगर आप इसे पढ़ते हैं, तो मैंने आपका जवाब केवल इसलिए नहीं चुना क्योंकि ऐसा लगता है कि आप साइट का उपयोग नहीं करते हैं! – adriandz

1

सवालों का युगल दिमाग में आते हैं:

  1. फ्रीज समय एक महीने से भी कम समय अवधि के लिए हो सकता है?
  2. यदि हां, तो नवीकरण तिथि बदल जाती है? या आंशिक महीने के लिए मासिक भुगतान कैसे लागू किया जाता है?

इससे प्रभावित होते हैं कि आपकी घटना कतार प्रणाली कैसे काम कर सकती है, लेकिन आखिरकार सदस्यता भुगतान के प्रबंधन को नहीं बदलती है।

सदस्यता समस्याओं को हल करने का एक तरीका सदस्यता भुगतान की एक अमूर्त तालिका बनाना है। यदि वे एक वर्ष के लिए मासिक भुगतान कर रहे हैं, तो तालिका में बारह भुगतान कतारबद्ध हैं। एक साप्ताहिक ग्राहक के पास उसी वर्ष तालिका में 52 भुगतान हो सकते हैं। हर बार नवीनीकरण की तारीख आती है, यह जांचने के बाद कि क्या फ्रीज मौजूद है या नहीं, अगला भुगतान लागू करें।

अमूर्तकरण तालिका ट्रैक रखती है कि कौन से भुगतान किए गए हैं। यदि कोई खाता रद्द नहीं होता है, तो भुगतान न किए गए पंक्तियां वापस की जाती हैं। यदि कोई खाता आपकी इवेंट कतार के अनुसार जमा हो जाता है, तो कोई भुगतान लागू नहीं होता है और जब तक खाता खराब नहीं हो जाता तब तक तालिका स्थिर रहती है।

उत्तर

ऐसा लगता है कि आप नवीकरण परिशोधन तालिका में निर्मित की तारीख की अवधारणा है। मैं एक कतार के रूप में अमूर्तकरण तालिका का अधिक उपयोग करता हूं, और सदस्यता के साथ अगली नवीनीकरण तिथि रखता हूं।

यदि नवीनीकरण तिथि अमूर्तकरण तालिका के साथ निहित है, तो हाँ, चीजों को साथ ही बदलना जटिल होगा। हालांकि, नवीनीकरण तिथि केवल उस दिन को प्रभावित करनी चाहिए जिस पर आप यह देखने के लिए जांच करते हैं कि कोई अन्य भुगतान लागू होता है या नहीं।

यदि आप सदस्यता के दौरान आंशिक भुगतान संरक्षित कर रहे हैं, और यदि होल्ड एक अनिर्दिष्ट अवधि के लिए हो सकता है, तो अमूर्तकरण तालिका पर अवधि मूल्य होने से आप कतार में आंशिक भुगतान वापस कर सकते हैं भुगतान में शेष शेष समय के बराबर अवधि के साथ "क्रेडिट" राज्य। इस तरह जब खाता खराब हो जाता है, वह आंशिक क्रेडिट पहले लागू होता है और आप शेष अवधि से अगली नवीनीकरण तिथि की गणना करते हैं।

इस बिंदु पर भुगतान आदेश को सुरक्षित रखने के लिए आदेशित सूची का कुछ रूप उपयोग करें। यह आसानी से आता है कि कोई भी ग्राहक सेवा कारणों के लिए नवीनीकरण अवधि के क्रेडिट के बराबर डालना चाहता है।

+0

मैंने आपके प्रश्न का जवाब देने के लिए अपना प्रश्न संपादित किया है (टिप्पणी बॉक्स में पर्याप्त कमरा नहीं)। – adriandz

संबंधित मुद्दे