2009-12-16 13 views
36

आज मेरे साथ एक सहयोगी के साथ एक चर्चा हुई।क्या आप अपनी परियोजना में अपनाए गए तृतीय पक्ष पुस्तकालयों को लपेटना चाहिए?

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

मैं शब्द हमेशा से असहमत हैं, चर्चा log4j के बारे में पैदा हुई और मुझे लगता है कि अच्छी तरह से log4j का परीक्षण किया है और समय साबित एपीआई और कार्यान्वयन, और सब कुछ विचारणीय का अनुमान किया विन्यस्त किया जा सकता है और कुछ भी आप लपेट चाहिए वहाँ का दावा किया। यहां तक ​​कि यदि आप लपेटना चाहते हैं तो कॉमन-लॉगिंग और log5j जैसे साबित रैपर हैं।

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

मैं this दावा किया, और कहा कि रैपिंग विशिष्ट मामलों में ही किया जाना चाहिए:

  • क्या आप वाकई कैसे पुस्तकालय अपनी आवश्यकताओं फिट होगा
  • आप केवल एक पुस्तकालय का एक छोटा सा हिस्सा उपयोग करेगा (में नहीं हैं जो मामला आप केवल अपने एपीआई का एक हिस्सा बेनकाब कर सकते हैं)।
  • आप पुस्तकालय के एपीआई या कार्यान्वयन की गुणवत्ता के बारे में सुनिश्चित नहीं हैं।

मैंने यह भी बनाए रखा कि कभी-कभी आप लाइब्रेरी के बजाय अपना कोड लपेट सकते हैं। उदाहरण के लिए, अपने डेटाबेस से संबंधित कोड को डीएओ परत में डालने के बजाय, सभी हाइबरनेट को पूर्ववत रूप से लपेटने के बजाय।

ठीक है, अंत में यह वास्तव में एक प्रश्न नहीं है, लेकिन आपकी अंतर्दृष्टि, अनुभव और राय की अत्यधिक सराहना की जाती है।

+8

+1 "हमेशा" – BryanD

+0

शब्द के साथ समस्या उठाने के लिए defacto log4j wrapper के लिए SLF4J देखें। आप जो एपेंडर चाहते हैं वह हमेशा आपके द्वारा उपयोग किए जाने वाले किसी अन्य लॉगर के साथ होता है :( –

उत्तर

52

यह YAGNI के लिए एक आदर्श उदाहरण है:

  • इसे अपनी परियोजना
  • अनावश्यक रूप से बढ़ा इसे अपने डिजाइन को मुश्किल हो सकती है
  • यह कोई तात्कालिक लाभ
  • scenarion आप अधिक काम
  • है इसे लिखने के लिए कभी भी प्रकट नहीं हो सकता है
  • जब ऐसा होता है, तो आपके रैपर को पूरी तरह से फिर से लिखा जाना चाहिए ly क्योंकि यह उस कंक्रीट लाइब्रेरी के बहुत करीब से बंधे हुए हैं जिसका आप उपयोग कर रहे थे और नया एक एपीआई बस आपके साथ मेल नहीं खाता है।
+2

+ 1 यह बिल्कुल सबसे अच्छा कारण है। आप ऑफ-मौके पर कोड को डिज़ाइन, कार्यान्वित और फिर बनाए रखने का प्रयास क्यों करेंगे? बर्बाद समय और प्रयास – wheaties

+6

+100 आपके अंतिम बुलेट बिंदु – ChssPly76

+3

पर एक रैपर को पूरी तरह से लिखना एक * बहुत है * आपके आवेदन को पूरी तरह से लिखने से कम काम। फिर भी, मैं यागनी सिद्धांत से सहमत हूं, और पहली बार जब तक आपको इसकी आवश्यकता होती है तब तक एक रैपर लिखने पर रोक लगती है। –

4

लाइब्रेरी को लपेटने का निर्णय लेने का मुख्य कारक है या नहीं, इसका मतलब कोड पर लाइब्रेरी परिवर्तन पर असर होगा। जब एक पुस्तकालय केवल 1 वर्ग से बुलाया जाता है तो बदलती लाइब्रेरी का प्रभाव न्यूनतम होगा। यदि दूसरी ओर एक पुस्तकालय को सभी वर्गों में बुलाया जाता है तो एक रैपर अधिक संभावना है।/3 पार्टी पुस्तकालय की जो कुछ भी

+0

यह log4j को लपेटने के लिए एक तर्क है, जिसे आमतौर पर किसी भी वर्ग से कहा जाता है जो कुछ भी दूरस्थ रूप से जटिल करता है। – flybywire

4
  1. 3 पार्टी पुस्तकालय के चुनाव के आसपास किसी भी अनिश्चितता scalability/उपयुक्तता का परीक्षण करने के प्रोटोटाइप का उपयोग कर परियोजना के प्रारंभ में दिया प्लावित किया जाना चाहिए।

  2. यदि आप आगे बढ़ने और पूर्ण डी-युग्मन/अमूर्त समर्थन प्रदान करने का निर्णय लेते हैं तो इसे लागत और अंततः परियोजना प्रायोजक द्वारा अनुमोदित किया जाना चाहिए - आखिरकार यह एक व्यावसायिक निर्णय है क्योंकि किसी को इसके लिए भुगतान करना पड़ता है और काम आवश्यक है ऐसा करें (जब तक कि यह बिल्कुल तुच्छ नहीं है, इस मामले में एपीआई शायद कम जोखिम है)।

  3. आम तौर पर एक अनुभवी वास्तुकार एक तकनीक का चयन करेगा जिसे वे उचित रूप से आत्मविश्वास से प्राप्त कर सकते हैं, और अनुभव कर सकते हैं, और वे विश्वास कर रहे हैं कि ऐप के जीवनकाल में रहेंगे, अन्यथा वे निर्णय में किसी भी जोखिम को खत्म कर देंगे इस परियोजना में, इस प्रकार

3

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

जब आप एक बहुत ही सामान्य एपीआई के आसपास रैपिंग कोड का उपयोग करते हैं, जैसे कि हाइबरनेट या लॉग 4j आप नए डेवलपर्स को लाने में अधिक कठिन बनाते हैं। नए डेवलपर्स को अब एक पूरी नई एपीआई सीखनी है, जहां अगर आपने कोड लपेटा नहीं है तो वे तुरंत बहुत परिचित होंगे।

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

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

मैं निश्चित रूप से नहीं कह रहा हूं कि रैपिंग कोड हमेशा खराब होता है, लेकिन जैसा कि आपने कहा है, ऐसे कई कारक हैं जिन पर आपको विचार करना है।

8

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

दूसरी तरफ, इसका मतलब यह होगा कि आपको शामिल होने वाली हर छोटी पुस्तकालय के लिए एक रैपर लिखना होगा, जो शायद ओवरहेड की एक अस्वीकार्य राशि है।

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

यह निश्चित रूप से "हमेशा" स्थिति नहीं है। यह ऐसा कुछ है जो वांछनीय हो सकता है। लेकिन समय हमेशा वहां नहीं जा रहा है, और अंत में, यदि एक रैपर लिखने में घंटों लगते हैं और दीर्घकालिक कोड लाइब्रेरी में परिवर्तन कुछ कम होने जा रहे हैं, और तुच्छ ... परेशान क्यों?

+0

दोनों तरफ अच्छा हाथ से दिखता है। – BryanD

1

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

मेरी वृत्ति YAGNI (आपको इसकी आवश्यकता नहीं है) सिद्धांत से अपील करना है और "शायद ही कभी" चुनना है।

2

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

  • अगर बहुत ज्यादा संशोधन और परिवर्धन की जरूरत है, यह सबसे अधिक संभावना है नहीं पुस्तकालय आप के लिए
  • लिए देख रहे हैं, अगर वहाँ अतिरिक्त और संशोधनों के एक उदार राशि है - वहाँ हमेशा डिजाइन पैटर्न है कि में काम आते हैं उन मामलों में। Decorator pattern (गतिशील रूप से मौजूदा ऑब्जेक्ट में नए/अतिरिक्त व्यवहार को जोड़ने की अनुमति देता है), उदाहरण के लिए, अधिकांश मामलों के लिए उपयुक्त है।
  • आईडीई खोज/प्रतिस्थापन और प्रतिस्थापन क्षमताओं यदि आपके पास कुछ महत्वपूर्ण परिवर्तन की आवश्यकता है और एक रैपिंग ऑब्जेक्ट दिखाई देता है तो सभी आवश्यक स्थानों में अपना कोड बदलने का एक आसान तरीका प्रदान करता है। (जाहिर है, यूनिट-परीक्षण यहाँ मददगार होगा;))
+1

द्वारा – flybywire

+0

हाँ, लेकिन अगर यह बहुत ही कम किया जाता है और यदि मामलों में यह एक पूर्ण आवश्यक है, तो समस्या बड़ी नहीं है। अभिव्यक्ति के लिए – Bozho

5

समस्या यहां आंशिक रूप से शब्द 'आवरण', आंशिक रूप से एक झूठी विरोधाभास है, और JDK के बीच आंशिक रूप से एक झूठी भेद और बाकी सब कुछ है।

शब्द 'आवरण'

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

हाइबरनेट निर्भरताओं को दूसरी ओर, एक पहचान, नियंत्रित, स्रोत फ़ाइलों के सेट पर प्रतिबंधित करना, व्यावहारिक हो सकता है और एक ही परिणाम प्राप्त कर सकता है। मानकों:

झूठी विरोधाभास

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

झूठी भेद

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

3

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

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

5

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

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

मैं केवल अगर मुझे यकीन है कि मैं उत्पादन में एक से अधिक और काफी अलग पुस्तकालयों का समर्थन करने के लिए होता है के लिए पता था कि रैपर के साथ जाना होगा।

+1

+1 "पहुंच सिद्धांतों, रूपकों और मुहावरे" – flybywire

3

यह एक अजीब सवाल की तरह है।

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

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

इसके अलावा, अपने सहयोगी "पुस्तकालयों" कहा जाता है चीजों को रेखा खींचना है? जावा के बारे में क्या? क्या वह अंतर्निहित कक्षाओं को लपेटता है? क्या वह फाइल सिस्टम को लपेटता है? थ्रेड शेड्यूलर? कर्नेल? (यानी, अपने स्वयं के रैपर के साथ - एक अर्थ में, सब कुछ सीपीयू के चारों ओर एक रैपर है, लेकिन ऐसा लगता है जैसे वह आपके स्रोत रेपो में रैपर के बारे में बात कर रहा है जो पूरी तरह से आपके नियंत्रण में हैं।) मैंने बनाया है- कार्यक्षमता में परिवर्तन या गायब हो जाते हैं जब इसके नए संस्करण प्रकट होते हैं। जावा इससे प्रतिरक्षा नहीं है।

तो विचार हमेशा लिखने के लिए एक रैपर एक शर्त पर आता है।

  • "प्रथम-पक्ष" कार्यक्षमता (जावा ही है, गिरी, आदि)
  • जब "तीसरी कभी नहीं बदलेगा: मान लिया जाये कि वह केवल तीसरे पक्ष के पुस्तकालयों लपेटकर है, वह परोक्ष कि सट्टेबाजी किया जा रहा है पार्टी "कार्यक्षमता में परिवर्तन होता है, यह हमेशा एक तरीके से किया जाएगा जिसे एक रैपर में तय किया जा सकता है

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

1

मैं इसे एक से एक चीज़ के रूप में लपेटूंगा, लेकिन मैं ऐप को ले जाऊंगा ताकि प्रत्येक भाग जितना संभव हो सके इसे बदलने योग्य हो। ISO OSI मॉडल सभी प्रकार के सॉफ़्टवेयर के लिए अच्छी तरह से काम करता है :-)

3

एक ऐसी स्थिति है जहां आप अच्छे कारण से लपेट सकते हैं। अर्थात् यदि आपको सामान का परीक्षण करने की आवश्यकता है, और डिफ़ॉल्ट तृतीय पक्ष ऑब्जेक्ट भारी वजन है। फिर एक इंटरफेस होने से वास्तव में एक फर्क पड़ सकता है।

नोट, यह लाइब्रेरी को प्रतिस्थापित नहीं करना है, लेकिन इसे प्रबंधित करने योग्य बनाएं जहां इससे कोई फर्क नहीं पड़ता।

4

नहीं जावा वास्तुकार/वन्ना-मधुमक्खी काल्पनिक परिवर्तनों के खिलाफ बहुत व्यस्त डिजाइनिंग हैं।

आधुनिक आईडीई के साथ, जब आपको परिवर्तन की आवश्यकता होती है तो यह केक का एक टुकड़ा है। तब तक, इसे सरल रखें।

+1

+1 "काल्पनिक परिवर्तनों के खिलाफ बहुत व्यस्त डिजाइनिंग" के लिए +1 – flybywire

5

मैं जो कुछ भी कहा गया है उससे सहमत हूं।

तृतीय पक्ष कोड लपेटने का एकमात्र समय उपयोगी है (बार YAGNI का उल्लंघन करने वाला बार) इकाई परीक्षण के लिए है।

मॉकिंग स्टेटिक्स और आगे के लिए आपको कोड लपेटने की आवश्यकता है, यह तृतीय पक्ष कोड के लिए रैपर लिखने का एक वैध कारण है।

लॉगिंग कोड के मामले में, इसकी आवश्यकता नहीं है।

1

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

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

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

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