जब एक अलग रूट में एक और AR होना चाहिए (और कब नहीं होना चाहिए)


15

मुझे पहले पोस्ट की लंबाई के लिए माफी माँगने से शुरू करें, लेकिन मैं वास्तव में बहुत विस्तार से सामने बताना चाहता था ताकि मैं आपका समय टिप्पणियों में आगे और पीछे न जाऊं।

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

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

एप्लिकेशन एक वेब क्लाइंट है जो एक RESTful सेवा इंटरफ़ेस के माध्यम से उजागर बैक-एंड सर्वर को कॉल करता है। सहज ज्ञान युक्त, पठनीय URL बनाने में मेरा पहला पास निम्नलिखित दो समापन बिंदुओं में हुआ:

http://myhost/employees/{id}/clockin
http://myhost/employees/{id}/clockout

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

सर्वर पर, मेरे पास एक एप्लिकेशन सेवा है जो एपीआई प्रदान करती है। ClockIn विधि के लिए मेरा प्रारंभिक विचार कुछ इस प्रकार है:

public void ClockIn(String id)
{
    var employee = EmployeeRepository.FindById(id);

    if (employee == null) throw SomeException();

    employee.ClockIn();

    EmployeeRepository.Save();
}

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

इसलिए, यदि मैं ऊपर दिखाए गए कोड के साथ जाता हूं, तो मेरी रिपॉजिटरी को यह पहचानना होगा कि एम्प्लॉई की स्थायी संपत्तियों में बदलाव नहीं हुआ है, लेकिन यह कि कर्मचारी के टाइमशीट में एक नई प्रविष्टि जोड़ी गई और डेटा स्टोर में एक इंसर्ट किया गया।

दूसरी ओर (और यहां पोस्ट का अंतिम प्रश्न), TimeSheet ऐसा लगता है जैसे यह एक एग्लिग्रेट रूट है और साथ ही इसकी पहचान (कर्मचारी आईडी और अवधि) है और मैं सिर्फ उसी तर्क को लागू कर सकता हूं जैसे TimeSheet.ClockIn (कर्मचारी कामतत्व)।

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


मैंने पोस्ट को एडिट / अपडेट किया है इसलिए प्रश्न स्पष्ट है और बेहतर परिदृश्य (उम्मीद) का उपयोग करता है।
SonOfPirate

जवाबों:


4

मैं समय की ट्रैकिंग के लिए एक सेवा को लागू करने के लिए इच्छुक हूं:

public interface ITimeSheetTrackingService
{
   void TrackClockIn(Employee employee, Timesheet timesheet);

   void TrackClockOut(Employee employee, Timesheet timesheet);

}

मुझे नहीं लगता कि यह टाइम शीट की ज़िम्मेदारी है कि आप इसे घड़ी में देखें, न ही यह कर्मचारी की ज़िम्मेदारी है।


3

अलग-अलग जड़ों को एक दूसरे को शामिल नहीं करना चाहिए (हालांकि उनमें दूसरों के लिए आईडी हो सकती है)।

सबसे पहले, TimeSheet वास्तव में एक कुल जड़ है? तथ्य यह है कि यह पहचान है यह एक इकाई बनाता है, जरूरी नहीं कि एक एआर। नियमों में से एक को देखें:

Root Entities have global identity.  Entities inside the boundary have local 
identity, unique only within the Aggregate.

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

मान लें कि आपके पास ARs, ClockIn और ClockOut है, जो Employee की तुलना में TimeSheet ऑपरेशंस की तरह अधिक हैं। आपकी सेवा परत विधि कुछ इस तरह दिख सकती है:

public void ClockIn(String employeeId)
{
    var timeSheet = TimeSheetRepository.FindByEmployeeAndTime(employeeId, DateTime.Now);    
    timeSheet.ClockIn();    
    TimeSheetRepository.Save();
}

यदि आपको वास्तव में कर्मचारी और टाइमशीट दोनों में क्लॉक-इन स्टेट को ट्रैक करने की आवश्यकता है, तो डोमेन ईवेंट पर एक नज़र डालें (मुझे विश्वास नहीं है कि वे इवांस की किताब में हैं, लेकिन ऑनलाइन कई लेख हैं)। यह कुछ इस तरह दिखाई देगा: Employee.ClockIn () EmployeeClockedIn ईवेंट उठाता है, जिसे एक ईवेंट हैंडलर उठाता है और बदले में TimeSheet.LogEmployeeClockIn () कहता है।


मैं आपकी बातों को देखता हूं। हालाँकि, कुछ नियम हैं जो किसी कर्मचारी को कब और कहाँ से रोक सकते हैं, इसके लिए बाध्य हैं। ये नियम अधिकतर कर्मचारी की वर्तमान स्थिति से प्रेरित होते हैं जैसे कि उन्हें समाप्त किया जाता है, पहले से ही क्लॉक-इन, उस दिन या यहाँ तक कि काम करने के लिए निर्धारित किया जाता है। वर्तमान पारी, आदि TimeSheet इस ज्ञान के अधिकारी चाहिए?
SonOfPirate

3

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

एक समग्र रूट में कभी भी एक और कुल रूट नहीं होना चाहिए।

आपके विवरण में, आपके पास एक कर्मचारी इकाई है , और इसी तरह एक टाइमशीट इकाई है। ये दो संस्थाएँ अलग-अलग हैं, लेकिन एक दूसरे के संदर्भ शामिल कर सकती हैं (उदाहरण: यह बॉब की टाइमशीट है)।

वह मूल मॉडलिंग है।

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

आप जो वर्णन करते हैं, उसके आधार पर, Timesheet.clockIn और Timesheet.clockOut को यह निर्धारित करने की आवश्यकता नहीं है कि कमांड की अनुमति है या नहीं यह निर्धारित करने के लिए कर्मचारी के किसी भी डेटा की जांच करें। तो इस समस्या के लिए, दो अलग-अलग एआर उचित लगते हैं।

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

दूसरी ओर (और यहां पोस्ट का अंतिम प्रश्न), टाइमशीट ऐसा लगता है जैसे यह एक एग्रिगेट रूट है और साथ ही इसकी पहचान (कर्मचारी आईडी और अवधि) है

पहचान का मतलब केवल यह एक इकाई है - यह व्यवसाय के अपरिवर्तनीय है जो ड्राइव करता है कि क्या इसे एक अलग कुल रूट माना जाना चाहिए।

हालाँकि, कुछ नियम हैं जो किसी कर्मचारी को कब और कहाँ से रोक सकते हैं, इसके लिए बाध्य हैं। ये नियम अधिकतर कर्मचारी की वर्तमान स्थिति से प्रेरित होते हैं जैसे कि उन्हें समाप्त किया जाता है, पहले से ही क्लॉक-इन, उस दिन या यहाँ तक कि काम करने के लिए निर्धारित किया जाता है। वर्तमान पारी, आदि TimeSheet इस ज्ञान के अधिकारी चाहिए?

हो सकता है - कुल चाहिए। यह जरूरी नहीं कि Timesheet चाहिए।

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

एक समुच्चय की एक जड़ इकाई है; इसे पहचानना पहेली का हिस्सा है। यदि किसी कर्मचारी के पास एक से अधिक Timesheet है, और वे दोनों एक ही कुल का हिस्सा हैं, तो Timesheet निश्चित रूप से मूल नहीं है। जिसका अर्थ है कि एप्लिकेशन सीधे टाइमशीट में आदेशों को संशोधित या प्रेषित नहीं कर सकता है - उन्हें रूट ऑब्जेक्ट (संभवतः कर्मचारी) को भेजा जाना चाहिए, जो कुछ जिम्मेदारी सौंप सकता है।

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

एक तरफ के रूप में, यह संभावना नहीं है कि आपके समुच्चय समय की अपनी भावना होनी चाहिए। इसके बजाय, उन्हें समय दिया जाना चाहिए

employee.clockIn(when);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.