5

जानकारी छिपाने की इच्छा को संतुलित करने के लिए प्रक्रिया (या फ़ंक्शन, मॉड्यूल इत्यादि) डिज़ाइन में कुछ सामान्य सर्वोत्तम प्रथाएं क्या हैं और प्रक्रिया के इंटरफ़ेस में अबास्ट्रक्शन का उपयुक्त स्तर शुरू करने में निहित समस्याओं के साथ निर्भरता निर्भर करता है?सूचना छिपाने बनाम छिपी निर्भरता

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

एक ही स्थिति किसी भी समय बाहरी संसाधन - फ़ाइल, डेटाबेस, जो कुछ भी उपयोग करती है, वही स्थिति होगी। प्रक्रिया के भीतर उस संसाधन के उपयोग को हार्ड-कोड करने के लिए किसी भी तरह गलत लगता है, लेकिन मुझे यकीन नहीं है कि विकल्प क्या है।

कृपया ध्यान दें कि मैं किसी ऑब्जेक्ट उन्मुख भाषा में काम नहीं कर रहा हूं; यथासंभव संभव है, मुझे उन प्रतिक्रियाओं में सबसे अधिक दिलचस्पी होगी जो किसी भी प्रकार की भाषा में व्यापक रूप से लागू होते हैं।

धन्यवाद, मैट

+1

क्या आपकी भाषा फ़ंक्शन पॉइंटर्स का समर्थन करती है? फ़ंक्शन पॉइंटर्स पर –

+0

+1। इस समस्या के आस-पास लगभग कोई भी समाधान किसी भी तरह से फ़ंक्शन पॉइंटर्स तक उबालने जा रहा है। – kyoryu

+0

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

उत्तर

0

आप संदर्भ/पर्यावरण वस्तु के कुछ प्रकार प्रदान कर सकता है। कहें:

type Environment = record 
     DatabaseHandle: ...; 
     ... 
    end; 

    Employee = record 
     ID: integer; 
     Name: string; 
     ... 
    end; 


function OpenEnvironment (var Env: Environment): boolean; 
begin 
    ... 
end; 

procedure CloseEnvironment (var Env: Environment); 
begin 
    ... 
end; 

function GetEmployeeById (var Env: Environment; ID: integer; var Employee: Employee): boolean; 
begin 
    ... load employee using the data source contained in environment ... 
end; 

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

इस दृष्टिकोण की कमी यह है कि आपको अपने सभी एपीआई को अतिरिक्त तर्क देना होगा।

1

यह हल करने के लिए एक बहुत ही मुश्किल मुद्दा है, चाहे आपकी कार्यान्वयन भाषा ऑब्जेक्ट उन्मुख है या नहीं (और किसी भी मामले में ऑब्जेक्ट पद्धतियां आमतौर पर लागू की जा सकती हैं चाहे प्रोग्रामिंग भाषा उन्हें भाषा निर्माण के रूप में समर्थन दे, चाहे मैंने वर्णित किया हो वस्तुओं के संदर्भ में मेरा समाधान)

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

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

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

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

तो सारांशित करने के लिए, व्यापार तर्क से पूरी तरह से डेटा वापसी को अलग करने के लिए, जैसा कि आप वर्णित छिपी निर्भरता में कुछ बहुत ही ग़लत नुकसान हैं। आईएमएचओ यह एक "ऑब्जेक्ट" के निर्माण के भीतर या किसी संग्रहीत डेटा से किसी संपत्ति को पुनर्प्राप्त करने के लिए किसी फ़ंक्शन के भीतर विशिष्ट डेटा की पुनर्प्राप्ति को समाहित करने के लिए एक विरोधी पैटर्न है।

0

आप यहाँ एक तीन परत दृष्टिकोण का उपयोग कर सकते हैं, अपनी पहली परत आप ग्राहक है, एक उपभोक्ता getEmployeePhoneNbr (EmployeeID) ... दूसरी परत अपने डेटा का उपयोग परत, और तीसरी परत है डेटा कार्यान्वयन परत होगी जिसका उपयोग जानकारी के ठोस स्रोत तक पहुंचने के लिए आपके डेटा एक्सेस लेयर द्वारा किया जाएगा।

डेटा कार्यान्वयन परत।

इस परत में शामिल हैं:

  1. एक डेटा संरचना है कि एक संसाधन को डेटा स्तर से पहुँचा जा सकता है के स्थान प्रतिनिधित्व करते हैं।
  2. एक नई संरचना बनाने के लिए एक एपीआई और इसे कॉन्फ़िगर करने के लिए इसके संवाददाता कार्य।

डेटा का उपयोग परत

शामिल है:

  1. डेटा संरचना के लिए एक सूचक डेटा के स्रोत के रूप में इस्तेमाल किया जाना है।
  2. प्राप्त करने के लिए सभी कॉल के साथ एक सार्वजनिक सरल एपीआई, getEmployeePhoneNbr (कर्मचारी आईडी), getEmployeeName (staffId) प्राप्त करें .... ये सभी कॉल डेटा डेटा संरचना में आंतरिक डेटा का उपयोग विशिष्ट डेटा
  3. तक पहुंचने के लिए करेंगे

इस दृष्टिकोण का उपयोग करने से आपको केवल डेटा डेटा परत पर सही डेटा कार्यान्वयन संरचना प्रदान करने का ख्याल रखना होगा, इसलिए यदि यह बदलता है, तो आपको केवल इसे एक ही स्थान पर बदलना होगा।

3

आपके पास जिस तरह की समस्या है, आमतौर पर निर्भरता उलटा सिद्धांत (उर्फ डीआईपी) का उपयोग करके हल किया जाता है। मूल लेख here पाया जा सकता है।

लेख मुख्य रूप से ओओ है लेकिन आप एक अनिवार्य भाषा में भी आवेदन कर सकते हैं (आप अनिवार्य भाषा के साथ ओओ कर सकते हैं यह कठिन है)।

सिद्धांत यह है कि क्लाइंट ऑब्जेक्ट को उस ऑब्जेक्ट का संदर्भ देना बेहतर होता है जो कोड की तुलना में कुछ आवश्यक प्रोसेसिंग (उदाहरण के लिए डेटाबेस एक्सेस) करता है या इस ऑब्जेक्ट को क्लाइंट ऑब्जेक्ट में जोड़ता है।

फ़ंक्शन स्तर पर आप उच्च स्तरीय फ़ंक्शन निम्न स्तर के डेटा/फ़ंक्शंस देने के लिए इसका अनुवाद कर सकते हैं।

गैर ओओ भाषा में सबसे अच्छा तरीका एक संरचना या फ़ंक्शन पॉइंटर को पास करना है जो उच्च स्तरीय फ़ंक्शन द्वारा उपयोग किए गए डेटा/फ़ंक्शंस को परिभाषित करता है।

0

संसाधन निर्भरता को लुकअप फ़ंक्शन में रखें। यदि कई संसाधन संबंधित हैं तो मैं एक मॉड्यूल तैयार करूंगा जिसमें उन्हें पुनर्प्राप्त करने के लिए सरल कार्य हो। जब मैं बच सकता हूं तो मैं व्यक्तिगत रूप से ऐसे संदर्भों को सौंपने से बचता हूं। जिस तरह से कोड को जानने या उनका उपयोग करने का कोई व्यवसाय नहीं है।

बजाय:

getEmployeePhoneNbr(employeeId) 
    dbName = "employeedb" 
    ... SQL, logic, etc. 

या:

getEmployeePhoneNbr(employeeId, dbName) 
    ... SQL, logic, etc. 

मैं क्या करना होगा निम्नलिखित:

getEmployeePhoneNbr(employeeId) 
    dbName = getEmployeeDbName() 
    ... SQL, logic, etc. 

इस तरह आप getEmployeeDbName (बदल सकते हैं) और हर निर्भर समारोह और मॉड्यूल फ़ायदा मिलेगा।