decoupling
यह अंततः हमारे संकलक और लिंकर्स की विशेषताओं की बारीकियों से रहित सबसे मौलिक डिजाइन स्तर पर दिन के अंत में मुझे डिकॉउलिंग करने के बारे में है। मेरा मतलब है कि आप ऐसा कर सकते हैं जैसे प्रत्येक हेडर को केवल एक वर्ग परिभाषित करें, पिंपल्स का उपयोग करें, आगे की घोषणाओं को उन प्रकारों के लिए करें जिन्हें केवल घोषित किए जाने की आवश्यकता है, परिभाषित नहीं, शायद हेडर का भी उपयोग करें जिसमें केवल आगे की घोषणाएं शामिल हैं (पूर्व:) <iosfwd>
, एक हेडर प्रति स्रोत फ़ाइल घोषित / परिभाषित, आदि के प्रकार के आधार पर सिस्टम को लगातार व्यवस्थित करें।
"संकलन-समय निर्भरता" को कम करने की तकनीक
और कुछ तकनीकें थोड़ी बहुत मदद कर सकती हैं, लेकिन आप इन प्रथाओं से खुद को मुक्त कर सकते हैं और फिर भी अपने सिस्टम में अपनी औसत स्रोत फ़ाइल ढूंढ सकते हैं, दो पेजों की प्रस्तावना चाहिए #include
यदि आप अपने इंटरफ़ेस डिज़ाइनों में तार्किक निर्भरता को कम किए बिना हेडर स्तर पर संकलन-समय की निर्भरता को कम करने पर बहुत अधिक ध्यान केंद्रित करते हैं, तो आसमान छूते बिल्ड समय के साथ कुछ भी सार्थक करने के निर्देश, और जबकि यह नहीं माना जाता है कि "स्पेगेटी हेडर" कड़ाई से बोलते हुए, मैं अभी भी कहना है कि यह व्यवहार में उत्पादकता के लिए समान हानिकारक मुद्दों का अनुवाद करता है। दिन के अंत में यदि आपकी संकलन इकाइयों को अभी भी कुछ भी करने के लिए दृश्यमान जानकारी की एक नाव की आवश्यकता होती है, तो यह बढ़ते समय का अनुवाद करने वाला है और आपको संभावित रूप से पीछे जाने के कारणों को गुणा करना होगा और डेवलपर्स बनाते समय चीजों को बदलना होगा। ऐसा लगता है कि वे सिस्टम को हेडबेट कर रहे हैं बस अपने दैनिक कोडिंग को समाप्त करने की कोशिश कर रहे हैं। यह
उदाहरण के लिए, आप प्रत्येक सबसिस्टम को एक बहुत सार हैडर फ़ाइल और इंटरफ़ेस प्रदान कर सकते हैं। लेकिन अगर सबसिस्टम एक दूसरे से अलग नहीं होते हैं, तो आपको उप-प्रणाली के साथ फिर से स्पेगेटी जैसा दिखने वाला कुछ मिलता है जो निर्भरता ग्राफ के साथ अन्य सबसिस्टम इंटरफेस पर निर्भर करता है जो काम करने के लिए एक गड़बड़ की तरह दिखता है।
बाहरी प्रकारों के लिए आगे की घोषणा
उन सभी तकनीकों में से, जिनके निर्माण के लिए मुझे पहले वाले कोडबेस को प्राप्त करने की कोशिश करने में दो घंटे लग गए, जबकि डेवलपर्स ने कभी-कभी हमारे बिल्ड सर्वरों पर सीआई के लिए अपनी बारी के लिए 2 दिन इंतजार किया (आप लगभग उन मशीनों को बोझ के रूप में थकाने वाले जानवरों के रूप में कल्पना कर सकते हैं। जब डेवलपर्स अपने बदलावों को आगे बढ़ाते हैं, तो असफल रहते हैं और अन्य हेडर में परिभाषित प्रकारों की घोषणा करना मेरे लिए सबसे अधिक संदेहास्पद था। और मैंने "कोडक स्पेगेटी" को कम करने की कोशिश करते हुए, उस छोटे से वृद्धिशील चरणों में ऐसा करने की उम्र के बाद 40 मिनट तक के कोडबेस को कम करने का प्रबंधन किया, जो कि हेंडसाइट में सबसे अधिक संदिग्ध अभ्यास है (जैसा कि मुझे मौलिक प्रकृति की दृष्टि खोने में मदद करता है। डिजाइन जबकि सुरंग हेडर अन्योन्याश्रितियों पर देखा गया) अन्य हेडर में परिभाषित प्रकारों को घोषित करने के लिए आगे था।
यदि आप एक Foo.hpp
हेडर की कल्पना करते हैं जिसमें कुछ ऐसा है:
#include "Bar.hpp"
और यह केवल Bar
हेडर में एक तरह से उपयोग करता है जिसके लिए इसे घोषणा की आवश्यकता होती है, परिभाषा की नहीं। तब यह हेडर में दिखाई देने वाली class Bar;
परिभाषा को बनाने से बचने के लिए घोषित करने के लिए एक नो-ब्रेनर की तरह लग सकता है Bar
। व्यवहार में छोड़कर अक्सर आप या तो अधिकांश संकलन इकाइयाँ प्राप्त कर लेंगे जिनका उपयोग Foo.hpp
अभी भी समाप्त करने की आवश्यकता Bar
है, वैसे भी Bar.hpp
खुद को शीर्ष पर शामिल करने के अतिरिक्त बोझ के साथ परिभाषित होने की आवश्यकता है Foo.hpp
, या आप किसी अन्य परिदृश्य में चलते हैं जहाँ वास्तव में मदद मिलती है और 99 आपकी संकलन इकाइयों में से% बिना शामिल किए काम कर सकते हैं Bar.hpp
, इसके अलावा यह अधिक मौलिक डिजाइन प्रश्न उठाता है (या कम से कम मुझे लगता है कि इसे आजकल होना चाहिए) कि उन्हें भी घोषणा करने की आवश्यकता Bar
क्यों है और क्योंFoo
यहां तक कि इसके बारे में जानने के लिए परेशान होने की जरूरत है कि क्या यह अधिकांश उपयोग के मामलों के लिए अप्रासंगिक है (एक निर्भरता के साथ एक डिजाइन का बोझ क्यों है?
क्योंकि वैचारिक रूप से हम वास्तव में इससे अलग Foo
नहीं हुए हैं Bar
। हमने अभी-अभी इसे बनाया है, इसलिए हैडर के हेडर के Foo
बारे में अधिक जानकारी की आवश्यकता नहीं है Bar
, और यह लगभग एक डिज़ाइन के रूप में पर्याप्त नहीं है जो वास्तव में इन दोनों को एक दूसरे से पूरी तरह से स्वतंत्र बनाता है।
एंबेडेड स्क्रिप्टिंग
यह वास्तव में बड़े पैमाने पर कोडबेस के लिए है, लेकिन एक अन्य तकनीक जो मुझे बहुत उपयोगी लगती है वह है आपके सिस्टम के कम से कम सबसे उच्च-स्तरीय भागों के लिए एक एम्बेडेड स्क्रिप्टिंग भाषा का उपयोग करना। मैंने पाया कि मैं एक दिन में लुआ को एम्बेड करने में सक्षम था और हमारे सिस्टम में सभी कमांड को समान रूप से कॉल करने में सक्षम था (कमांड्स सार थे, शुक्र है)। दुर्भाग्य से मैं एक ऐसी सड़क पर भाग गया, जहाँ देवों ने एक और भाषा का परिचय दिया, और शायद सबसे विचित्र, प्रदर्शन के साथ उनके सबसे बड़े संदेह के रूप में। फिर भी जब मैं अन्य चिंताओं को समझ सकता था, तो प्रदर्शन एक गैर-मुद्दा होना चाहिए, यदि हम केवल स्क्रिप्ट का उपयोग करने के लिए कमांड का उपयोग करते हैं जब उपयोगकर्ता बटन पर क्लिक करते हैं, उदाहरण के लिए, जो अपने स्वयं के कोई विषम छोरों का प्रदर्शन नहीं करते हैं (हम क्या करने की कोशिश कर रहे हैं, एक बटन क्लिक के लिए प्रतिक्रिया समय में नैनोसेकंड अंतर के बारे में चिंता?)।
उदाहरण
इस बीच सबसे प्रभावी तरीका मैंने कभी-कभी बड़े कोडबिस में संकलित समय को कम करने की तकनीक को समाप्त करने के बाद देखा है, ऐसे आर्किटेक्चर हैं जो वास्तव में काम करने के लिए सिस्टम में किसी भी एक चीज के लिए आवश्यक जानकारी की मात्रा को कम करते हैं, न कि एक कंपाइलर से दूसरे से एक हेडर को डिकम्पोज करना। परिप्रेक्ष्य, लेकिन इन इंटरफेस के उपयोगकर्ताओं को यह जानने की आवश्यकता होती है कि उन्हें क्या करना है (जानते हुए भी दोनों एक मानव और संकलक दृष्टिकोण से, सही डिकम्पलिंग जो संकलक निर्भरता से परे जाती है) नंगे न्यूनतम।
ईसीएस केवल एक उदाहरण है (और मैं आपको एक का उपयोग करने का सुझाव नहीं दे रहा हूं), लेकिन इसका सामना करने से पता चला कि आपके पास कुछ वास्तव में महाकाव्य कोडबेस हो सकते हैं जो अभी भी आश्चर्यजनक रूप से जल्दी से निर्माण करते हैं, जबकि खुशी से टेम्पलेट्स और बहुत सारे अन्य का उपयोग करते हैं क्योंकि ईसीएस, द्वारा प्रकृति, एक बहुत ही विकृत आर्किटेक्चर बनाता है जहां सिस्टम को केवल ECS डेटाबेस के बारे में जानने की आवश्यकता होती है और आमतौर पर केवल कुछ ही प्रकार के घटक प्रकार (कभी-कभी केवल एक) को अपनी चीज़ करने के लिए:
डिजाइन, डिजाइन, डिजाइन
और एक मानव में इस तरह के डीकॉउंड आर्किटेक्चरल डिज़ाइन, वैचारिक स्तर कम से कम उन तकनीकों की तुलना में अधिक प्रभावी है, जो मैंने ऊपर बताई गई तकनीकों में से किसी के रूप में देखीं, क्योंकि आपका कोडबेस बढ़ता और बढ़ता है, और बढ़ता है, क्योंकि यह वृद्धि आपके औसत में अनुवाद नहीं करती है। संकलन इकाई काम के लिए आवश्यक मात्रा की जानकारी को गुणा करती है और काम करने के लिए लिंक समय (किसी भी प्रणाली जिसे आपके औसत डेवलपर को कुछ भी करने के लिए सामान की एक नाव को शामिल करने की आवश्यकता होती है, और कुछ भी करने के लिए जानकारी के एक महान सौदे के बारे में जानने के लिए केवल संकलक की आवश्यकता नहीं होती है )। बिल्ड टाइम और अनटैंगिंग हेडर की तुलना में इसके अधिक लाभ हैं, क्योंकि इसका मतलब यह भी है कि आपके डेवलपर्स को सिस्टम के बारे में ज्यादा जानने की जरूरत नहीं है कि इसके साथ कुछ करने के लिए तुरंत क्या आवश्यक है।
यदि, उदाहरण के लिए, आप अपने एएए गेम के लिए एक भौतिकी इंजन विकसित करने के लिए एक विशेषज्ञ भौतिकी डेवलपर को नियुक्त कर सकते हैं, जो लाखों एलओसी तक फैला है, और वह पूरी तरह से नंगे न्यूनतम जानकारी को जानते हुए भी शुरू कर सकता है जहां तक कि प्रकार और इंटरफेस जैसी चीजें उपलब्ध हैं। साथ ही साथ आपके सिस्टम की अवधारणाएं, फिर वह स्वाभाविक रूप से अपने भौतिकी इंजन का निर्माण करने के लिए उसके और संकलक दोनों के लिए कम मात्रा में जानकारी का अनुवाद करने जा रही है, और इसी तरह निर्माण समय में बड़ी कमी का अनुवाद करती है जबकि आम तौर पर यह अर्थ लगाया जाता है कि कुछ भी नहीं है। सिस्टम में कहीं भी। और यही मैं इन सभी अन्य तकनीकों से ऊपर प्राथमिकता देने का सुझाव दे रहा हूं: आप अपने सिस्टम को कैसे डिजाइन करते हैं। यदि आप इसे करते हैं, तो अन्य तकनीकों को शीर्ष पर टुकड़े करना होगा, अन्यथा,