क्या यह एक कोड गंध है यदि कोई वस्तु अपने मालिक का बहुत कुछ जानता है?


9

हमारे डेल्फी 2007 आवेदन में हम निम्नलिखित निर्माण का एक बहुत उपयोग कर रहे हैं

FdmBasic:=TdmBasicData(FindOwnerClass(AOwner,TdmBasicData));

FindOwnerClass एक विशिष्ट वर्ग (उदाहरण TDMBasicData) खोजने के लिए वर्तमान घटक के मालिक पदानुक्रम को ऊपर की ओर ले जाता है। परिणामी वस्तु को फ़ील्ड चर FDMBasic में संग्रहीत किया जाता है। हम इसका उपयोग मुख्य रूप से डेटाटोडुल्स को पारित करने के लिए करते हैं।

उदाहरण: एक रिपोर्ट बनाते समय, परिणामी डेटा को संकुचित किया जाता है और एक datamodule TDMReportBaseData के माध्यम से एक्सेस की गई तालिका के ब्लॉब फ़ील्ड में संग्रहीत किया जाता है। हमारे आवेदन के एक अलग मॉड्यूल में, रिपोर्टबेडल का उपयोग करके डेटा को पृष्ठांकित रूप में रिपोर्ट दिखाने की कार्यक्षमता है। इस मॉड्यूल (TDMRBReport) का मुख्य कोड, कंप्रेस्ड ब्लॉब डेटा को अलग-अलग टेबलों में बदलने के लिए एक TRBTempdatabase का उपयोग करता है, जो कि रिपोर्टबिल्डर रनटाइम रिपोर्टडेसिग्नर में प्रयोग करने योग्य होते हैं। TDMRBReport में सभी प्रकार के रिपोर्ट-संबंधित डेटा (रिपोर्ट का प्रकार, रिपोर्ट की गणना, आदि) के लिए TDMReportBaseData तक पहुंच है। TRBTempDatabase TDMRBReport में निर्मित है, लेकिन TDMReportBedata तक पहुँच है। तो यह अब ऊपर निर्माण का उपयोग करके किया जाता है:

constructor TRBTempDatabase.Create(aOwner: TComponent);
begin
  inherited Create(aOwner);

  FdmReportBaseData := TdmRBReport(FindOwnerClass(Owner, TdmRBReport)).dmReportBaseData;
end;{- .Create }

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

इस बारे में आपके विचार क्या हैं? क्या यह एक कोड गंध है? यदि हां, तो बेहतर तरीका क्या है?


1
यदि यह जानना चाहिए कि किसी अन्य वर्ग के बारे में यह करने का एक आसान तरीका प्रदान किया गया है।
लोरेन Pechtel

जवाबों:


13

इस तरह का एक सर्विस लोकेटर पैटर्न दिखता है, जिसे सबसे पहले मार्टिन फाउलर द्वारा वर्णित किया गया था (जिसे एक सामान्य पैटर्न के रूप में पहचाना गया है)।

निर्माण आधारित निर्भरता इंजेक्शन एक सेवा लोकेटर पर पसंद किया जाता है क्योंकि यह आवश्यक मापदंडों की दृश्यता को बढ़ावा देता है और सरल इकाई परीक्षण को बढ़ावा देता है।

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

कंपाइलर इंजेक्शन का उपयोग करने पर कंपाइलर उपभोक्ताओं और उत्पादकों दोनों को इतनी मदद दे सकता है, लेकिन एपीआई के लिए ऐसी कोई भी सहायता उपलब्ध नहीं है जो सेवा लोकेटर पर निर्भर हो।

इसके अलावा, विशेष रूप से यह कानून के कानून को भी तोड़ता है

लॉ ऑफ़ डेमेटर (LoD) या सिद्धांत का सिद्धांत, विकासशील सॉफ्टवेयर, विशेष रूप से ऑब्जेक्ट-ओरिएंटेड प्रोग्राम के लिए एक डिज़ाइन गाइडलाइन है। अपने सामान्य रूप में, LoD ढीली युग्मन का एक विशिष्ट मामला है।

फ़ंक्शंस के लिए कानून के कानून की आवश्यकता है कि ऑब्जेक्ट O का एक तरीका M केवल निम्न प्रकार की वस्तुओं के तरीकों को लागू कर सकता है:

  1. ओ ही है
  2. एम के मापदंडों
  3. M के भीतर बनाई गई कोई भी वस्तु / त्वरित
  4. ओ के प्रत्यक्ष घटक वस्तुओं
  5. एक वैश्विक चर, O के द्वारा सुलभ, M के दायरे में

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

बेहतर तरीका है

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

constructor TRBTempDatabase.Create(aOwner: TComponent, ownerClass: IComponent);
begin
  inherited Create(aOwner);

  FdmReportBaseData := TdmRBReport(ownerClass).dmReportBaseData;
end;{- .Create }

3
शानदार जवाब, और जो कोई भी इस अद्भुत सादृश्य के साथ आया है:As a simple example, when one wants to walk a dog, it would be folly to command the dog's legs to walk directly; instead one commands the dog and lets it take care of its own legs.
एंडी हंट

3

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

इस बात पर निर्भर करता है कि आपकी दो कक्षाएं कितनी गहराई से जुड़ी हुई हैं, यह थोड़ा सा लगता है जैसे कि फ़ीवर ईर्ष्या या अनुचित अंतरंगता कोड गंध का विवरण स्पष्ट है।

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

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