a-philosophy-of-software-design

Rob Zapp द्वाराअभी तक कोई इंस्टॉल नहींअभी तक कोई लाइक नहीं8 अक्टूबर 2026 को अपडेट किया गयाश्रेणी: इंजीनियरिंग

यह क्या करता है

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

इंस्टॉल करने पर यह एंट्री आपके AgentsRoom डेस्कटॉप ऐप में खुलती है। अगर ऐप अभी इंस्टॉल नहीं है, तो आपको डाउनलोड पेज पर भेज दिया जाएगा।

SKILL.md

---
name: a-philosophy-of-software-design
description: कोड लिखते, बदलते या समीक्षा करते समय उपयोग करें जब भी परिवर्तन एक निर्यात या आयात योग्य नाम जोड़ता है, एक मॉड्यूल, क्लास, कंपोनेंट, हेल्पर, हुक, सेवा या रैपर बनाता है, दोहराए गए कोड को केंद्रीकृत करता है, या API बदलता है। Ousterhout नियम (गहरे मॉड्यूल, सूचना छुपाना, जटिलता को नीचे लाना) के साथ-साथ साझा कोड के लिए अपरिवर्तनीय परीक्षण, रीडर-कॉस्ट परीक्षण, और अंत में एक आवश्यक डिज़ाइन नोट।
---

# सॉफ़्टवेयर डिज़ाइन का एक दर्शन (जॉन ऑस्टरहाउट)

## इस कौशल का उपयोग कब करें

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

## सुधारने के लिए पूर्वाग्रह

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

## निर्णय नियम

- डिज़ाइन को इस आधार पर मापें कि यह जटिलता को कितना कम करता है। उस डिज़ाइन को प्राथमिकता दें जो पाठक के बोझ को कम करता है। जटिलता के चार संकेत हैं। एक परिवर्तन के लिए कई जगहों पर संपादन की आवश्यकता होती है। निर्भरताएँ छिपी होती हैं। कदम एक निश्चित क्रम में होने चाहिए। पाठक को कई तथ्यों को याद रखना पड़ता है।
- डिज़ाइन को निरंतर कार्य के रूप में मानें। एक पहला पैच जो काम करता है, तब तक पूरा नहीं होता जब तक वह बाद के परिवर्तनों को कठिन न बना दे। इंटरफ़ेस, मॉड्यूल विभाजन या अमूर्तता के बारे में निर्णय के लिए, दो या अधिक संभावित डिज़ाइनों की तुलना करें।
- गहरे मॉड्यूल को प्राथमिकता दें। एक गहरा मॉड्यूल छोटा इंटरफ़ेस रखता है और बड़ी जटिलता को छुपाता है। पास-थ्रू सेवाओं, पतले लाइब्रेरी रैपर और छोटे सहायक मॉड्यूल को अस्वीकार करें। कोई भी ऐसा निष्कर्षण अस्वीकार करें जो नाम जोड़ता है लेकिन पाठक के बोझ को कम नहीं करता।
- इंटरफ़ेस को उस आधार पर डिज़ाइन करें जो कॉलर को जानना चाहिए, न कि इस आधार पर कि कार्यान्वयन कैसे काम करता है। नाजुक सेटअप अनुक्रम, मोड फ्लैग, कॉन्फ़िगरेशन नॉब और आर्गुमेंट्स से बचें जो आंतरिक विकल्प दिखाते हैं।
- उन निर्णयों को छुपाएं जो बदल सकते हैं। उदाहरण हैं आंतरिक प्रतिनिधित्व, संग्रहण आकार, प्रोटोकॉल, फ़ाइल स्वरूप और प्रदर्शन ट्रिक्स। बहीखाता, सामान्यीकरण और किनारे के मामले अन्य उदाहरण हैं। प्रत्येक को उस मॉड्यूल के अंदर रखें जो उस ज्ञान का मालिक है।
- जटिलता को उस मॉड्यूल में नीचे खींचें जो विवरण का मालिक है। एक अधिक जटिल कार्यान्वयन स्वीकार करें जब यह कॉलर्स को सरल अनुबंध देता है और प्रत्येक कॉल साइट से दोहराए गए कार्य को हटाता है।
- एक मॉड्यूल को सही स्तर पर सामान्य बनाएं। एक मॉड्यूल को केवल एक कॉलर के लिए फिट न करें। भविष्य की जरूरतों के लिए अस्पष्ट अमूर्तता न जोड़ें। दुर्लभ किनारे के मामलों को मुख्य मार्ग से बाहर रखें, और विशेष व्यवहार को उसके अपने स्थान पर रखें।
- कुल जटिलता के आधार पर मॉड्यूलों को जोड़ें या विभाजित करें। आकार, कोड के चलने के क्रम, आदत या दिखावट के आधार पर उन्हें न जोड़ें या विभाजित करें। संबंधित स्थिति, व्यवहार, नियम और निर्णयों को साथ रखें। उन्हें केवल तब विभाजित करें जब नई सीमा गहरी हो और पाठक प्रत्येक पक्ष को अकेले समझ सके।
- अपवादों के सेट को छोटा बनाएं। जहां संभव हो, इंटरफ़ेस या नियमों को बदलें ताकि अमान्य स्थिति न हो सके। हर कॉलर को एक ही रक्षात्मक कोड दोहराने के लिए मजबूर न करें।
- जटिलता को कम करने के लिए टिप्पणियों का उपयोग करें। इंटरफ़ेस अनुबंध, नियम जो सत्य बने रहना चाहिए, छिपे डिज़ाइन निर्णय और उनके कारण लिखें। साथ ही कठिन तथ्य लिखें जिन्हें कॉलर्स को जानने की आवश्यकता नहीं हो। कोड को टिप्पणी में दोहराएं नहीं। खराब नाम, खराब विभाजन या भ्रमित नियंत्रण प्रवाह को छुपाने के लिए टिप्पणी का उपयोग न करें।
- नाम, सुसंगतता और स्पष्टता को डिज़ाइन जानकारी के रूप में मानें। एक नाम पाठक को अमूर्तता बताता है, तंत्र नहीं। संबंधित संचालन एक ही कन्वेंशन का उपयोग करते हैं। कोड जो पाठक को आश्चर्यचकित करता है, जटिलता जोड़ता है, भले ही वह छोटा हो।
- सार्वजनिक अनुबंधों और स्थिर API के खिलाफ परीक्षण लिखें। उन अनुबंधों के माध्यम से छिपी जटिलता और विशेष मामलों का परीक्षण करें। परीक्षण की आसानी के कारण सतही या लीक इंटरफ़ेस को न अपनाएं।
- प्रदर्शन परिवर्तन, पैटर्न, पैरेडाइम या फ्रेमवर्क केवल दो कारणों में से एक के लिए जोड़ें। यह इस कोडबेस में जटिलता को कम करता है, या सबूत दिखाता है कि ट्रेड-ऑफ आवश्यक है। प्रत्येक अनुकूलन को स्थिर इंटरफ़ेस के पीछे छुपाएं।

## संकेत और प्रत्येक के लिए प्रतिक्रिया

- कोई फीचर अजीब है, या एक परिवर्तन फ़ाइलों में फैलता है, या समीक्षक को छिपी निर्भरताएँ खोजनी पड़ती हैं। प्रतिक्रिया: गायब सूचना छुपाने और सतही मॉड्यूल देखें। साथ ही निश्चित क्रम में कदम और कॉलर्स द्वारा वहन की गई जटिलता देखें।
- आप एक मॉड्यूल, लेयर, सेवा, सहायक, रैपर या फेसाड जोड़ते हैं। या आप एक पैटर्न, विकल्प, कॉलबैक या आर्गुमेंट जोड़ते हैं। प्रतिक्रिया: दिखाएं कि यह जितनी जटिलता जोड़ता है उससे अधिक छुपाता है।
- आप API बदलते हैं। प्रतिक्रिया: जांचें कि एक सामान्य कॉलर को क्या जानना चाहिए। कॉलर को कॉल के क्रम, प्रतिनिधित्व या संग्रहण की आवश्यकता नहीं होनी चाहिए। कॉलर को ट्रांसपोर्ट, कैश, प्रोटोकॉल या फ़ाइल स्वरूप की आवश्यकता नहीं होनी चाहिए। कॉलर को आंतरिक वर्कफ़्लो या कई सेटअप चरणों की आवश्यकता नहीं होनी चाहिए।
- आप एक विशेष मामला, फ्लैग, अपवाद पथ, स्थिति या कंटेनर जोड़ते हैं जिसे कॉलर्स देख सकते हैं। प्रतिक्रिया: पहले पूछें कि मालिकाना मॉड्यूल इसके बजाय क्या कर सकता है। यह अमान्य स्थिति हटा सकता है, असामान्य व्यवहार को अलग कर सकता है या मजबूत ऑपरेशन दे सकता है।
- आप कोड विभाजित करते हैं, फ़ंक्शन निकालते हैं या एक वेरिएबल जोड़ते हैं। प्रतिक्रिया: जांचें कि नई सीमा या नाम अर्थपूर्ण है। यह केवल कूद, गुजरने वाली स्थिति या मध्यवर्ती चरण नहीं जोड़ना चाहिए जिन्हें कॉलर्स देख सकते हैं।
- कोड में चरण होते हैं जैसे `prepare`, `process` और `finalize`, या कॉलर्स को वस्तुओं को चरणों में बनाना पड़ता है। प्रतिक्रिया: जांचें कि समय क्रम वास्तविक अवधारणा है। यदि नहीं, तो कोड को स्थिर जिम्मेदारियों के चारों ओर व्यवस्थित करें।
- कोई नाम अस्पष्ट है, तंत्र का नाम है, सुसंगत नहीं है या पाठक को आश्चर्यचकित करता है। प्रतिक्रिया: अमूर्तता सीमा के बारे में फिर से सोचें। लगभग सही नाम स्वीकार न करें।
- कोई टिप्पणी लंबी है, कोड दोहराती है, भ्रमित इंटरफ़ेस समझाती है, या उपयोग समझाने के लिए आंतरिक दिखाती है। प्रतिक्रिया: अमूर्तता बदलें, या गायब अनुबंध को इंटरफ़ेस में ले जाएं।
- आप प्रदर्शन अनुकूलित करते हैं। प्रतिक्रिया: पहले मापें, फिर अनुकूलन छुपाएं। बिना सबूत के कि ट्रेड-ऑफ आवश्यक है, मॉड्यूल की गहराई या सूचना छुपाने को न छोड़ें।
- आप परीक्षण या समीक्षा करते हैं। प्रतिक्रिया: सार्वजनिक व्यवहार और इंटरफ़ेस अनुबंध देखें। साथ ही स्थिर API के पीछे छिपी जटिलता और अमूर्तता के पीछे रखे विशेष मामलों को देखें।

## अंतिम चेकलिस्ट

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

## गेट

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

## अपरिवर्तनीय परीक्षण: केवल वह कोड साझा करें जो साथ में बदलता है

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

## रीडर लागत: तीसरा परीक्षण

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

- **खोजने योग्य।** प्रत्येक अवधारणा के लिए एक नाम का उपयोग करें। इसे हर जगह समान वर्तनी में लिखें, ताकि सादा टेक्स्ट खोज इसे पाए। दोष: स्ट्रिंग से बने नाम, आयात साइड इफेक्ट्स के माध्यम से वायरिंग, एक अवधारणा के लिए दो नाम। परिभाषा छुपाने वाली पुनः-निर्यात श्रृंखलाएं भी दोष हैं।
- **जल्दी रोकें।** अनुबंध को फ़ाइल के शीर्ष या निर्यात के ऊपर रखें। बताएं कि यह क्या वादा करता है, क्या छुपाता है और क्या कभी नहीं करता। फिर पाठक जल्दी रुक सकता है।
- **मशीन-चेक करने योग्य।** प्रत्येक सीमा के अंदर और बाहर सटीक प्रकारों का उपयोग करें, ताकि टाइपचेक कॉलर्स को पढ़ने की जगह ले सके। दोष: `any`, सादा डिक्शनरी, बूलियन फ्लैग जिनका अर्थ केवल बॉडी में होता है।
- **दृश्य जुड़ाव।** दो जगहों को एक साथ बदलना चाहिए। इसे साझा प्रकार, परीक्षण या एकल स्रोत से लागू करें। यदि आप नहीं कर सकते, तो दोनों जगहों पर इसे चिह्नित करें।
- **कोई शोर नहीं।** कोड की पुनरावृत्ति करने वाली टिप्पणियां और टिप्पणी की गई कोड हटाएं। मृत शाखाएं और परिवर्तन इतिहास रिकॉर्ड करने वाली टिप्पणियां हटाएं। पुराने मार्ग को हटाएं जो उसके प्रतिस्थापन के पास रहता है।
- **पूर्वानुमेय।** रिपॉजिटरी की मौजूदा व्यवस्था का पालन करें। परीक्षण को उस जगह रखें जहां पाठक उसे खोजता है, और इसे अकेले चलाएं।

फ़ाइल का आकार जानबूझकर इस सूची में नहीं है। एक बहुत बड़ी फ़ाइल एक छिपे हुए दूसरे निर्णय की तलाश का कारण है। यह फ़ाइल को काटने का कारण कभी नहीं है।

## सुरक्षा

मौजूदा कोड के लिए, पहले एक परीक्षण लिखें जो वर्तमान व्यवहार को बनाए रखे। फिर मॉड्यूल को गहरा बनाएं। नए कोड के लिए, वह परीक्षण लिखें जो इच्छित व्यवहार को परिभाषित करता है।

## डिज़ाइन नोट (जब गेट लागू हो)

जब गेट लागू हो, तो पुल अनुरोध के विवरण में `## Design note` शीर्षक के साथ एक अनुभाग डालें। दो से चार पंक्तियाँ लिखें:

- प्रत्येक सीमा जो आपने जोड़ी, और वह निर्णय जो वह छुपाता है।
- प्रत्येक डुप्लिकेशन जिसे आपने जानबूझकर रखा, और कारण।
- प्रत्येक सतही भाग जिसे आपने स्वीकार किया, और कारण।

यदि गेट लागू नहीं होता, तो `## Design note` लिखें और उसके बाद `Gate not applicable: <reason>` लिखें। डिज़ाइन नोट को अपनी अंतिम चरण की सारांश में भी डालें।

## समीक्षा मोड

जब आप किसी अन्य एजेंट या व्यक्ति द्वारा लिखा गया कोड समीक्षा या परीक्षण करें, तो इस अनुभाग का उपयोग करें।

1. डिज़ाइन नोट जांचें। जब गेट लागू हो और पुल अनुरोध में `## Design note` अनुभाग न हो, तो एक ब्लॉकिंग फाइंडिंग रिपोर्ट करें। जब नोट डिफ़ के साथ मेल न खाए, तो ब्लॉकिंग फाइंडिंग रिपोर्ट करें।
2. एक डिज़ाइन फाइंडिंग तभी ब्लॉकिंग होती है जब यह दोनों शर्तें पूरी करे:
   - यह इस कौशल के नियम का नाम लेता है। नियम एक निर्णय नियम, गेट, अपरिवर्तनीय परीक्षण या एक रीडर-कॉस्ट आइटम है।
   - यह पाठक या अगले परिवर्तन के लिए एक ठोस लागत बताता है। उदाहरण: "कॉलर्स को स्टोरेज आकार पता होना चाहिए।" "एक अवधारणा के दो नाम हैं।" "एक कैप परिवर्तन को तीन फ़ाइलों में संपादन की आवश्यकता है।"
3. हर अन्य डिज़ाइन अवलोकन को गैर-ब्लॉकिंग के रूप में चिह्नित करें। इसे "Non-blocking design notes" शीर्षक वाली अलग सूची में रखें। एक गैर-ब्लॉकिंग नोट कभी भी काम को बिल्डर को वापस नहीं भेजता।
4. प्राथमिकता को फाइंडिंग के रूप में रिपोर्ट न करें। एक अलग नाम, फ़ाइल व्यवस्था या शैली प्राथमिकता है। यह केवल तब फाइंडिंग बनती है जब यह नामित नियम को तोड़ती है और ठोस लागत होती है।
5. जब वही डिज़ाइन फाइंडिंग दूसरे समीक्षा चक्र में वापस आए, तो इसे बढ़ाएं। एक ही परिवर्तन तीसरी बार न मांगें।

## संबंधित कौशल (जब स्थापित हों)

- `find-shared-code`: हाल के इतिहास में साझा करने योग्य कोड के लिए केवल रिपोर्ट-आधारित खोज। यह इस कौशल के अपरिवर्तनीय परीक्षण और गहराई परीक्षण का उपयोग करता है।
- `refactoring` और `working-effectively-with-legacy-code`: गहरे डिज़ाइन की ओर सुरक्षित कदम। यह कौशल तय करता है कि नई सीमा बनी रहती है या नहीं।

## स्रोत और लाइसेंस

यह स्किल GitHub पर ciembor/agent-rules-books रिपॉजिटरी में "A Philosophy of Software Design" के "मिनी" नियमों पर आधारित है (MIT लाइसेंस, कमिट 893a88a)। गेट, इनवेरिएंट टेस्ट, रीडर-कॉस्ट टेस्ट, डिजाइन नोट और रिव्यू मोड उन नियमों में अतिरिक्त हैं। रिपॉजिटरी में पुस्तक के पूर्ण नियम भी मौजूद हैं।

टैग

designarchitectureousterhoutreview

और जानें

AgentsRoom डाउनलोड करें

अपने सभी AI एजेंट्स को, अपने सभी प्रोजेक्ट्स पर, एक ही विंडो से चलाएं।

मुफ़्तAgentsRoom डाउनलोड करें

कंपेनियन ऐप: चलते-फिरते अपने एजेंट्स मॉनिटर करें

Claude, Codex, Antigravity CLI या किसी अन्य AI प्रदाता का उपयोग करें।

एक्सटेंशन इंस्टॉल करें
Chrome Web Store

बग और अनुरोध सीधे अपने सार्वजनिक बैकलॉग में भेजें।

मल्टी-प्रोजेक्ट
मल्टी-प्रोवाइडर
मल्टी-एजेंट
लाइव स्टेटस
फाइल डिफ और कमिट
मोबाइल ऐप
लाइव प्रीव्यू
एजेंट टीमें
ब्राउज़र ऑटोमेशन
बैकलॉग-संचालित डेव
प्रॉम्प्ट लाइब्रेरी
स्किल्स लाइब्रेरी
सभी सुविधाएँ देखें