परिचय: C++ के संदर्भ में SOLID
\nSOLID — रॉबर्ट मार्टिन द्वारा प्रतिपादित ऑब्जेक्ट-ओरिएंटेड डिज़ाइन के पाँच मौलिक सिद्धांतों का संक्षिप्त नाम है। C++ के लिए, एक शक्तिशाली स्टैटिक टाइपिंग, एकाधिक वंशानुक्रम और RAII वाली भाषा के रूप में, ये सिद्धांत विशेष महत्व रखते हैं। उन्नत स्तर पर, SOLID को समझना लचीली, परीक्षण योग्य और विस्तार योग्य प्रणालियाँ बनाने में मदद करता है, साथ ही 'दैवीय वर्ग' या कठोर युग्मन जैसे एंटीपैटर्न से बचाता है।
\nइस लेख में, हम प्रत्येक सिद्धांत को C++ (17/20) के व्यावहारिक कोड उदाहरणों के साथ समझेंगे, कार्यान्वयन की बारीकियों पर ध्यान केंद्रित करते हुए: std::unique_ptr, std::function, CRTP, वर्चुअल डिस्ट्रक्टर और आधुनिक इडियम का उपयोग।
1. Single Responsibility Principle (SRP) — एकल उत्तरदायित्व का सिद्धांत
\nसूत्रीकरण: एक वर्ग में परिवर्तन का केवल एक ही कारण होना चाहिए।
\nव्यवहार में, इसका अर्थ है कि वर्ग एक व्यावसायिक इकाई या एक संचालन के लिए उत्तरदायी है। SRP का उल्लंघन उत्तरदायित्वों के 'जुड़ाव' की ओर ले जाता है, जो परीक्षण और संशोधन को जटिल बनाता है।
\nउल्लंघन का उदाहरण
\nclass Report {\npublic:\n void generate() { /* डेटा निर्माण */ }\n void saveToFile(const std::string& path) { /* फ़ाइल में लिखना */ }\n void sendEmail(const std::string& to) { /* भेजना */ }\n};\nयहाँ Report निर्माण, सहेजने और भेजने के लिए उत्तरदायी है — परिवर्तन के तीन कारण।
SRP के साथ रीफैक्टरिंग
\nclass Report {\npublic:\n void generate() { /* डेटा निर्माण */ }\n};\n\nclass ReportSaver {\npublic:\n void save(const Report& report, const std::string& path);\n};\n\nclass EmailSender {\npublic:\n void send(const Report& report, const std::string& to);\n};\nअब प्रत्येक वर्ग का एक ही उत्तरदायित्व है। इससे मॉड्यूलर परीक्षण और पुन: उपयोग सरल हो जाता है।
\n\n2. Open/Closed Principle (OCP) — खुलेपन/बंदपन का सिद्धांत
\nसूत्रीकरण: सॉफ्टवेयर संस्थाएँ विस्तार के लिए खुली होनी चाहिए, लेकिन संशोधन के लिए बंद होनी चाहिए।
\nC++ में, इसे अक्सर पॉलीमॉर्फिज्म (वर्चुअल फंक्शन) या टेम्पलेट (CRTP) के माध्यम से कार्यान्वित किया जाता है। उन्नत स्तर के लिए, हम दोनों तकनीकों पर विचार करेंगे।
\nपॉलीमॉर्फिक दृष्टिकोण (वर्चुअल फंक्शन)
\nclass Shape {\npublic:\n virtual double area() const = 0;\n virtual ~Shape() = default;\n};\n\nclass Circle : public Shape {\n double r;\npublic:\n Circle(double r) : r(r) {}\n double area() const override { return 3.14 * r * r; }\n};\n\nclass Rectangle : public Shape {\n double w, h;\npublic:\n Rectangle(double w, double h) : w(w), h(h) {}\n double area() const override { return w * h; }\n};\nएक नई आकृति (जैसे Triangle) जोड़ने के लिए मौजूदा वर्गों में बदलाव की आवश्यकता नहीं है — केवल एक नया वंशज बनाना होगा।
टेम्पलेट दृष्टिकोण (CRTP — Curiously Recurring Template Pattern)
\ntemplate<typename Derived>\nclass ShapeBase {\npublic:\n double area() const { return static_cast<const Derived*>(this)->area_impl(); }\n};\n\nclass Circle : public ShapeBase<Circle> {\n double r;\npublic:\n Circle(double r) : r(r) {}\n double area_impl() const { return 3.14 * r * r; }\n};\nCRTP वर्चुअल कॉल के ओवरहेड के बिना स्टैटिक पॉलीमॉर्फिज्म प्रदान करता है, जो high-performance C++ के लिए महत्वपूर्ण है।
\n\n3. Liskov Substitution Principle (LSP) — बारबरा लिस्कोव का प्रतिस्थापन सिद्धांत
\nसूत्रीकरण: बेस क्लास की वस्तुओं को प्रोग्राम की शुद्धता को भंग किए बिना व्युत्पन्न वर्गों की वस्तुओं द्वारा प्रतिस्थापित किया जाना चाहिए।
\nC++ में LSP का उत्कृष्ट उल्लंघन पूर्व-शर्तों को कमजोर करके या बाद-शर्तों को मजबूत करके वर्चुअल विधि को ओवरराइड करना है। 'आयत — वर्ग' पदानुक्रम के साथ एक उदाहरण पर विचार करें।
\nएंटीपैटर्न
\nclass Rectangle {\nprotected:\