ousterhout-quality-program
यह क्या करता है
जब भी कोड लिखा या समीक्षा किया जा रहा हो और वह कोई सीमा बनाता या बदलता हो — जैसे नया मॉड्यूल, क्लास, कंपोनेंट, हेल्पर, हुक, सेवा, या रैपर; कोई भी साझा कोड का निष्कर्षण या केंद्रीकरण; कोई भी "आइए इसे पुन: उपयोगी बनाएं" क्षण — और जब स्पष्ट रूप से मॉड्यूल की समीक्षा, पुनर्गठन, या डिज़ाइन किया जा रहा हो, तब उपयोग करें। यह निर्णय करता है कि कोई अमूर्तता अपनी जगह बनाती है या नहीं: मॉड्यूल की गहराई, क्या डिज़ाइन निर्णय छुपाना है, क्या डुप्लिकेट कोड साझा अपरिवर्तनीयता की रक्षा करता है या केवल तुकबंदी करता है, क्या इंटरफ़ेस स्थिर है। यांत्रिक SOLID/Clean Code से बचाव करता है जो कई उथले क्लास बनाता है। साथ ही रीडर-कॉस्ट टेस्ट को परिभाषित करता है (ऐसा कोड जो मनुष्यों और एजेंट्स के लिए पढ़ने और बदलने में सस्ता हो) और मौजूदा कोडबेस को इस मानक पर पुनर्गठित करने की प्रक्रिया बताता है।
इंस्टॉल करने पर यह एंट्री आपके AgentsRoom डेस्कटॉप ऐप में खुलती है। अगर ऐप अभी इंस्टॉल नहीं है, तो आपको डाउनलोड पेज पर भेज दिया जाएगा।
SKILL.md
---
name: ousterhout-quality-program
description: जब भी कोड लिखा या समीक्षा किया जा रहा हो और वह कोई सीमा बनाता या बदलता हो — जैसे नया मॉड्यूल, क्लास, कंपोनेंट, हेल्पर, हुक, सेवा, या रैपर; कोई भी साझा कोड का निष्कर्षण या केंद्रीकरण; कोई भी "आइए इसे पुन: उपयोगी बनाएं" क्षण — और जब स्पष्ट रूप से मॉड्यूल की समीक्षा, पुनर्गठन, या डिज़ाइन किया जा रहा हो, तब उपयोग करें। यह निर्णय करता है कि कोई अमूर्तता अपनी जगह बनाती है या नहीं: मॉड्यूल की गहराई, क्या डिज़ाइन निर्णय छुपाना है, क्या डुप्लिकेट कोड साझा अपरिवर्तनीयता की रक्षा करता है या केवल तुकबंदी करता है, क्या इंटरफ़ेस स्थिर है। यांत्रिक SOLID/Clean Code से बचाव करता है जो कई उथले क्लास बनाता है। साथ ही रीडर-कॉस्ट टेस्ट को परिभाषित करता है (ऐसा कोड जो मनुष्यों और एजेंट्स के लिए पढ़ने और बदलने में सस्ता हो) और मौजूदा कोडबेस को इस मानक पर पुनर्गठित करने की प्रक्रिया बताता है।
---
# Ousterhout गुणवत्ता कार्यक्रम
## अवलोकन
किसी मॉड्यूल का काम जटिलता को एक छोटे इंटरफ़ेस के पीछे छुपाना होता है। मुख्य मापदंड है **गहराई**: एक गहरा मॉड्यूल महत्वपूर्ण कार्यक्षमता के ऊपर एक सरल इंटरफ़ेस प्रदान करता है; एक उथला मॉड्यूल का इंटरफ़ेस लगभग उतना ही जटिल होता है जितना उसका कार्यान्वयन, इसलिए यह अपने लिए कुछ भी भुगतान नहीं करता। जटिलता वह है जो आप महसूस करते हैं जब कोई परिवर्तन आपको उस कोड को समझने या छूने के लिए मजबूर करता है जिसकी आपने उम्मीद नहीं की थी — Ousterhout दो स्रोतों का नाम देता है: **निर्भरता** (आप A को बदले बिना B को नहीं बदल सकते) और **अस्पष्टता** (महत्वपूर्ण जानकारी स्पष्ट नहीं होती)।
Ousterhout अकेले आपको बताता है कि एक अच्छा मॉड्यूल कैसा *महसूस* होता है। यह सबसे मजबूत होता है जब इसे कुछ अन्य दृष्टिकोणों के साथ मिलाया जाता है जो आपको बताते हैं कि सीमाएं कहाँ होनी चाहिए और उन्हें सुरक्षित रूप से कैसे आगे बढ़ाया जाए। यह कौशल वह संयुक्त दृष्टिकोण है।
## समीक्षा वास्तव में कहाँ गलत होती है
यह कौशल जिन दो विफलताओं को सुधारने के लिए मौजूद है — जो एजेंट-लिखित कोड में बार-बार देखी गई हैं — वे **उपचार** में हैं, न कि विभाजन/अविभाजन के निर्णय में:
1. **उथला समाधान।** छह `as unknown as` कास्ट्स दिए जाने पर, बिना सहायता वाले समीक्षक उन्हें एक सामान्य `castRows<T>()` हेल्पर में केंद्रीकृत कर देते हैं — यह अधिक सुव्यवस्थित है, लेकिन अस्पष्टता बनी रहती है। गहरा समाधान है टाइप किए गए row→domain मैपर जो पहले परीक्षणों के साथ पिन किए गए हैं (Parnas लागू करते हुए: एक कास्ट एक गायब सीमा की गंध है; Beck: मैपिंग को साबित करें इससे पहले कि आप इसे स्थानांतरित करें)। गंध को साफ करना उसे हटाना नहीं है।
2. **स्वचालित निष्कर्षण।** तीन सहोदर घटकों में एक ही अपडेट लॉजिक दोहराए जाने पर, हर बिना सहायता वाले समीक्षक ने कहा "एक साझा हेल्पर निकालो" — DRY प्रतिक्रिया। इस कार्यक्रम का नियम, Metz का विस्तार करते हुए: तीसरे समान दिखने वाले के लिए नहीं, बल्कि अपरिवर्तनीय के लिए प्रतीक्षा करें — केंद्रीकृत करें जब कोड एक साझा नियम की रक्षा करता हो, न कि जब यह केवल समान हो।
जब आप खुद को कोई समाधान सुझाते हुए पाएं, तो इसे दोनों से जांचें: क्या यह अस्पष्टता को हटाता है या केवल उसे स्थानांतरित करता है, और क्या निष्कर्षण एक अपरिवर्तनीय की रक्षा करता है या केवल एक रूप को दोहराता है?
## अनुपातिकता द्वार
जब कोई परिवर्तन कोई नया निर्यात/आयात योग्य नाम नहीं जोड़ता, कोई नया मॉड्यूल/क्लास/कंपोनेंट/हेल्पर/हुक/सेवा/रैपर नहीं बनाता, और कुछ भी केंद्रीकृत नहीं करता, तो इस दृष्टिकोण को छोड़ दें। शुद्ध नाम परिवर्तन, यांत्रिक कोडमॉड, कॉन्फ़िग/डेटा संपादन, और एकल-पंक्ति सुधार छूट प्राप्त हैं। संदेह होने पर, केवल दो मुख्य परीक्षण (गहराई, अपरिवर्तनीय) चलाएं और वहीं रोक दें।
## पूरा नियम
हर उत्पन्न या समीक्षा किए गए कोड का Ousterhout दृष्टिकोण से परीक्षण किया जाता है इससे पहले कि कार्य को पूरा घोषित किया जाए — केवल स्पष्ट डिज़ाइन समीक्षाओं तक सीमित नहीं — सिवाय उन परिवर्तनों के जो अनुपातिकता द्वार के नीचे हैं (कोई नई सीमा नहीं, कोई केंद्रीकरण नहीं: नाम परिवर्तन, कोडमॉड, कॉन्फ़िग संपादन)। दो परीक्षण: (1) **गहराई** — एक नया इंटरफ़ेस उस चीज़ की तुलना में काफी अधिक छुपाना चाहिए जितना वह प्रकट करता है; एक ऐसा इंटरफ़ेस जो उतना ही जटिल हो जितना वह लपेटता है, कुछ भी भुगतान नहीं करता। (2) **अपरिवर्तनीय** — साझा कोड केवल तभी निकालें जब वह एक साझा नियम की रक्षा करता हो, कभी नहीं क्योंकि तीन स्थान समान हैं; और एक समाधान को अस्पष्टता को हटाना चाहिए, उसे केवल स्थानांतरित नहीं करना चाहिए (छह कास्ट्स को एक हेल्पर में केंद्रीकृत करना अभी भी छह कास्ट्स हैं)। जब कोई परिवर्तन सीमा बनाता है या उसे पुनः आकार देता है, तो पहले देखें कि एक स्थापित उत्पाद इस आकार और पैमाने की समस्या को कैसे हल करता है और उसके कन्वेंशंस को अपनाएं जब तक कि कोई स्पष्ट कारण न हो (प्रशिक्षण से याद किया गया पैटर्न दावा है, स्रोत नहीं), फिर नीचे दिए गए जांच करें।
## कब उपयोग करें
- यह तय करते समय कि कोई नया क्लास/फ़ंक्शन/हुक अपने इंटरफ़ेस के लायक है या केवल एक उथला पास-थ्रू है।
- एक फ़ाइल आकार सीमा पार कर जाती है और आप यह तय कर रहे हैं कि इसे *कैसे* विभाजित किया जाए, केवल यह नहीं कि आपको विभाजित करना चाहिए।
- बार-बार कोड आपको एक साझा हेल्पर निकालने के लिए प्रेरित करता है।
- किसी व्यवसाय नियम के चारों ओर सीमा डिज़ाइन या समीक्षा करते समय (जैसे प्राधिकरण स्कोप जांच, धन/राउंडिंग नियम, स्टेट-मशीन ट्रांज़िशन गार्ड, डेटा-रिटेंशन नियम)।
- एक इंटरफ़ेस एक पैरामीटर या विशेष मामले को बढ़ाने वाला हो।
- मौजूदा कोडबेस को इस मानक पर लाना — नीचे "इस मानक पर मौजूदा कोडबेस का पुनर्गठन" देखें।
**के लिए नहीं:** तुच्छ यांत्रिक संपादन, या जब कोई परियोजना कन्वेंशन पहले से संरचना निर्धारित करता हो — ऊपर अनुपातिकता द्वार देखें। जब उपलब्ध हों, तो `karpathy-guidelines` के लिए सर्जिकल-परिवर्तन अनुशासन और पुनर्गठन सुरक्षा नेट के लिए परीक्षण-चालित विकास कौशल को प्राथमिकता दें।
## दृष्टिकोण
प्रत्येक दृष्टिकोण केवल एक प्रश्न जोड़ता है। Ousterhout रीढ़ है; अन्य इसके अंधे स्थानों को सुधारते हैं।
| लेंस | यह कौन सा प्रश्न जोड़ता है | कब यह ओवरराइड करता है |
|---|---|---|
| **Ousterhout** — गहरे मॉड्यूल | क्या यह इंटरफ़ेस जितना प्रकट करता है उससे अधिक छुपाता है? | डिफ़ॉल्ट स्पाइन। |
| **Parnas** — सूचना छुपाना | कौन सा डिज़ाइन निर्णय (जो संभवतः बदलेगा) यह मॉड्यूल छुपाता है? | एक मॉड्यूल को गहरा होना चाहिए इसका *कारण*। यदि यह कुछ भी नहीं छुपाता जो बदलता है, तो गहराई केवल दिखावा है। |
| **Brooks** — आवश्यक बनाम आकस्मिक | क्या यह आकस्मिक जटिलता को हटाता है, या केवल आवश्यक डोमेन जटिलता को स्थानांतरित करता है? | "रिफैक्टर्स" को खत्म करता है जो गड़बड़ी को बिना कम किए स्थानांतरित करते हैं। |
| **Evans** — डोमेन-ड्रिवन डिज़ाइन | क्या यह सीमा डोमेन भाषा में नामित है, न कि सामान्य उपयोगिता भाषा में? | `utils`/`helpers` का नाम बदलें — सीमा का नाम उस अपरिवर्तनीय के अनुसार रखें जो इस रिपॉजिटरी में वास्तव में है। |
| **Fowler** — रिफैक्टिंग / गंध | गहरे डिज़ाइन की ओर सबसे छोटा सुरक्षित कदम क्या है? | "गहरा होना चाहिए" को परीक्षण पास करने वाले ठोस कदमों में बदलता है। |
| **Beck** — सरल डिज़ाइन, टेस्ट-फर्स्ट | क्या मैंने सीम को गहरा करने से पहले वर्तमान व्यवहार साबित किया है? | पूर्व समय से आर्किटेक्चर पर ब्रेक। पहले इसे काम करें और परीक्षण करें, फिर सही सीम को गहरा करें। |
| **Hickey** — सरल बनाम आसान | क्या यह असंबंधित अवधारणाओं को मिलाता है, या वास्तव में एक ही अवधारणा है? | एक उथला सहायक आमतौर पर *आसान* होता है (पास में, तेज़), न कि *सरल* (कम इंटरलीव्ड अवधारणाएं)। सरल को प्राथमिकता दें। |
| **Metz** — गलत अमूर्तता पर पुनरावृत्ति | क्या यह दोहराया कोड एक साझा अपरिवर्तनीय की रक्षा करता है, या केवल समान दिखता है (इस प्रोग्राम का नियम, Metz का विस्तार)? | Metz: गलत अमूर्तता से पुनरावृत्ति सस्ती है — गलत अमूर्तता को वापस इनलाइन करें बजाय इसे मोड़ने के। यह प्रोग्राम उसका विस्तार करता है: केवल इसलिए केंद्रीकृत न करें क्योंकि यह दोहराता है; केवल तब केंद्रीकृत करें जब यह एक वास्तविक अपरिवर्तनीय की रक्षा करता हो। अपरिवर्तनीय प्रकट होने तक पुनरावृत्ति सहन करें। |
| **Hyrum's Law** — प्रेक्षित व्यवहार | क्या कॉलर इस इंटरफ़ेस के अनुबंध से परे व्यवहार पर निर्भर होंगे? | छोटे, स्थिर इंटरफेस के पक्ष में तर्क: हर प्रेक्षित व्यवहार अंततः भार वहन करने वाला बन जाता है। |
## संयोजन विधि
इस क्रम में लागू करें — बाद के लेंस केवल तब मायने रखते हैं जब पहले वाले पास हो जाएं:
1. **Metz — प्रवेश द्वार।** क्या यह सीमा/अमूर्तता अस्तित्व के योग्य है? Metz का विस्तार करते हुए इस प्रोग्राम का नियम: केवल तभी निकालें जब कोड एक साझा नियम की रक्षा करता हो — तीन समान दिखने वाले अपरिवर्तनीय नहीं होते। यदि नहीं, तो यहीं रुकें।
2. **Parnas / Ousterhout** — अस्थिर निर्णय (प्राधिकरण स्कोप, राउंडिंग नियम, संक्रमण गार्ड, प्रतिधारण नियम) को एक गहरे मॉड्यूल के पीछे छुपाएं।
3. **Evans** — उस मॉड्यूल का नाम डोमेन भाषा में रखें, न कि `utils`।
4. **Beck / Fowler** — मौजूदा कोड के लिए, वर्तमान व्यवहार को परीक्षणों से पिन करें, फिर छोटे सुरक्षित कदमों में रिफैक्टर करें। ताजा जनरेट किए गए कोड के लिए कोई वर्तमान व्यवहार नहीं होता — इसके बजाय इच्छित व्यवहार को परिभाषित करने वाला परीक्षण लिखें।
5. **Hickey** — उन इंटरफेसों को अस्वीकार करें जो केवल वर्कफ़्लो समान दिखने के कारण असंबंधित अवधारणाओं को मिलाते हैं।
## संरचनात्मक एंटी-पैटर्न
**मैकेनिकल SOLID / क्लीन कोड उथले मॉड्यूल बनाता है।** एक कट्टरपंथी पढ़ाई —
एक जिम्मेदारी प्रति क्लास, हर फ़ंक्शन निकालें, सब कुछ छोटा रखें —
ऐसे क्लासों का झुंड बनाता है जिनके इंटरफेस उनके शरीर जितने जटिल होते हैं। जब कोई नियम कहता है "इसे विभाजित करें," तो पूछें कि विभाजन कौन सा *निर्णय* छुपाता है (Parnas) और क्या यह जितना प्रकट करता है उससे अधिक छुपाता है (Ousterhout)। यदि यह कुछ भी नहीं छुपाता जो बदलता है, तो विभाजित न करें। यह गार्ड रिफैक्टर दबाव के तहत सबसे महत्वपूर्ण होता है ("इसे साफ करें", "यह फ़ाइल बहुत बड़ी है") — शांत विश्लेषण में समीक्षक पहले से ही इसका विरोध करते हैं; मध्य-रिफैक्टर में, जब दृश्य परिवर्तन करने का आदेश होता है, तब उथली फ़ाइलों का झुंड लिखा जाता है।
## सामान्य गलतियाँ
- **सिर्फ आकार पर विभाजन।** एक 400-लाइन क्वेरी मॉड्यूल जो एक सुसंगत निर्णय छुपाता है, चार 100-लाइन मॉड्यूलों से गहरा हो सकता है जो समान जॉइंस लीक करते हैं।
- **विभाजन का नाम `helpers`/`utils` रखना।** यदि आप इसे डोमेन भाषा में नाम नहीं दे सकते (Evans), तो सीमा शायद गलत है।
- **दूसरी बार होने पर निकालना।** Metz का विस्तार करते हुए इस प्रोग्राम का नियम: अपरिवर्तनीय का इंतजार करें, तीसरे समान दिखने वाले का नहीं।
- **व्यवहार पिन किए बिना गहरा करना।** Beck: बिना परीक्षण के जो वर्तमान व्यवहार साबित करे, "गहरा" रिफैक्टर पुनर्लेखन है।
- **पास-थ्रू को मॉड्यूल समझना।** एक रैपर जो अपने तर्क अग्रेषित करता है, एक इंटरफ़ेस जोड़ता है और कुछ नहीं छुपाता — परिभाषा के अनुसार उथला।
- **राइम को अपरिवर्तनीय समझना।** साझा अपरिवर्तनीय का सबसे अच्छा प्रमाण सह-परिवर्तन है: प्रतियां इतिहास में एक साथ ठीक या बदली गई हैं (एक ही बग दो जगह ठीक किया गया)। स्वतंत्र रूप से बदलने वाले समान दिखने वाले राइम हैं; उन्हें दोहराया छोड़ दें।
- **गंध को साफ करने के बजाय हटाना।** छह कास्ट को एक सामान्य कास्ट सहायक में केंद्रीकृत करना उसी अस्पष्टता का साफ-सुथरा संस्करण है। गहरा समाधान उस सीमा का नाम देता है जिसे कास्ट छुपा रहा था।
## पाठक लागत: तीसरा परीक्षण
गहराई और अपरिवर्तनीय तय करते हैं कि कोई सीमा होनी चाहिए या नहीं। पाठक लागत तय करती है कि उसके आसपास का कोड बदलने में सस्ता है या नहीं। अगला पाठक, मानव या एजेंट, हर उस लाइन के लिए भुगतान करता है जिसे सुरक्षित रूप से बदलने के लिए उसे लोड करना पड़ता है। एजेंट टोकन में भुगतान करते हैं और टेक्स्ट खोज, आंशिक पढ़ाई और टाइपचेक/टेस्ट लूप द्वारा नेविगेट करते हैं, इसलिए वही दोष उनके लिए अधिक महंगे होते हैं। पूछें:
- **खोजने योग्य?** प्रत्येक अवधारणा के लिए एक नाम, हर जगह एक जैसा लिखा गया, सामान्य टेक्स्ट खोज से पहुंच योग्य। दोष: नाम स्ट्रिंग्स से बने होते हैं, आयात साइड इफेक्ट द्वारा वायरिंग, पुनः-निर्यात श्रृंखलाएं जो परिभाषा छुपाती हैं, एक अवधारणा के लिए दो नाम।
- **क्या पाठक जल्दी रुक सकता है?** अनुबंध फ़ाइल के शीर्ष पर या निर्यात के ऊपर होता है: यह क्या वादा करता है, क्या छुपाता है, क्या कभी नहीं करता। दोष: अनुबंध केवल बॉडी पढ़कर निकाला जा सकता है।
- **मशीन-चेक करने योग्य?** हर सीमा के अंदर और बाहर सटीक प्रकार, ताकि टाइपचेक कॉलर्स को पढ़ने की जगह ले सके। दोष: `any`, बिना टाइप के डिक्शनरी, बूलियन फ्लैग जिनका अर्थ बॉडी में रहता है।
- **क्या कपलिंग दिखाई देती है?** वे स्थान जो साथ में बदलने चाहिए, लागू होते हैं (एक साझा प्रकार, एक परीक्षण, एक स्रोत) या, असफल होने पर, दोनों साइटों पर चिह्नित होते हैं। छुपी हुई कपलिंग का प्रमाण इतिहास में सह-परिवर्तन है जिसे कोड में कहीं उल्लेख नहीं मिलता।
- **शोर-मुक्त?** कोई टिप्पणी जो कोड को दोहराती हो, कोई टिप्पणी की गई कोड, कोई मृत शाखाएं, कोई परिवर्तन-इतिहास टिप्पणियां, कोई अप्रचलित पथ जो उसके प्रतिस्थापन के बगल में रखा हो, नहीं।
- **पूर्वानुमेय?** लेआउट रिपो के मौजूदा पैटर्न का पालन करता है; परीक्षण वह जगह है जहां पाठक इसे खोजेगा और यह अपने आप चलता है।
फ़ाइल का आकार जानबूझकर अनुपस्थित है। एक बहुत बड़ी फ़ाइल एक दूसरी छुपी हुई निर्णय की तलाश का कारण हो सकती है, कभी कटौती का कारण नहीं: पाठक खोज और पढ़ सकते हैं, और एक विभाजन जो कुछ भी छुपाता नहीं, लोड हटाए बिना इंटरफेस जोड़ता है।
कोड में मार्कर और रिपो कोडमैप के लिए, जहां उपलब्ध हो `context-audit` का उपयोग करें: इसका `AIDEV-NOTE:` एंकर (एक गैर-पुनर्प्राप्त तथ्य प्लस एक स्रोत संदर्भ, अधिकतम दो लाइनें, साइट पर) कपलिंग के लिए परंपरा है जिसे लागू नहीं किया जा सकता।
## इस मानक के लिए मौजूदा कोडबेस का पुनर्गठन
एक रेट्रोफिट को नए कोड की तरह ही आंका जाता है; जो भिन्न होता है वह क्रम और संयम है। अधिकांश कोडबेस को वैसे ही छोड़ देना चाहिए।
1. **जनगणना, केवल-पढ़ने योग्य।** सीमाओं (मॉड्यूल, सेवाएं, साझा हेल्पर्स) की सूची बनाएं। प्रत्येक रिकॉर्ड के लिए: वह निर्णय जो यह छुपाता है, या "कोई नहीं"; इंटरफेस का आकार बनाम बॉडी; इतिहास से सह-परिवर्तन साथी; पाठक-लागत दोष। अभी कुछ न बदलें।
2. **चर्न के अनुसार रैंक करें, बदसूरती के अनुसार नहीं।** प्राथमिकता है कि कोड कितनी बार बदलता है और पढ़ने की लागत क्या है। काम करने वाला ठंडा कोड वैसे ही रहता है, चाहे वह कितना भी सतही हो। आवश्यक डोमेन जटिलता वहीं रहती है (Brooks)।
3. **प्रत्येक खोज के लिए एक उपाय निर्धारित करें:**
- पास-थ्रू लेयर या रैपर जो कुछ भी छुपाता नहीं: इसे हटा दें, कॉलर्स उस चीज़ का उपयोग करें जिसे यह लपेटता था;
- फ्लैग और विशेष मामलों से मुड़ा हुआ गलत अमूर्तता: इसे वापस इनलाइन करें (Metz), फिर असली अपरिवर्तनीय खोजें;
- सतही भाई जो एक निर्णय साझा करते हैं: उन्हें एक इंटरफेस के पीछे मर्ज करें;
- लीक हुआ निर्णय (कॉलर्स को फॉर्मेट, नियम, स्कीमा पता है): इसे उस मॉड्यूल में नीचे खींचें जो इसका मालिक है;
- सामान्य नाम (`utils`, `helpers`, `manager`): इसे उस निर्णय के लिए पुनः नामित करें जो यह छुपाता है, या इसे इसके कॉलर्स में विलय करें;
- बिना टाइप की सीमा: इसे टाइप करें, और कास्ट को उस मैपर से बदलें जिसे वे छुपा रहे थे;
- छुपी हुई कपलिंग: इसे लागू करें, या दोनों साइटों को चिह्नित करें;
- शोर: इसे हटा दें।
स्वतंत्र रूप से बदलने वाले तुकांतों को कोई उपाय नहीं मिलता।
4. **पहले व्यवहार पिन करें।** कोई उपाय तब तक शुरू न करें जब तक कि कोई परीक्षण उस कोड के वर्तमान व्यवहार को साबित न कर दे जिसे आप छू रहे हैं (Beck)। पुनर्गठन व्यवहार-संरक्षणीय होते हैं; व्यवहार परिवर्तन एक अलग कमिट है।
5. **काम को ऐसे इकाइयों में काटें जिन्हें एक एजेंट अकेले पूरा कर सके।** प्रति इकाई एक सीमा। प्रत्येक इकाई उन फ़ाइलों के नाम बताती है जो वह रखती है, वह अनुबंध जिसे उसे बनाए रखना है, और वह कमांड जो इसे स्वयं साबित करता है। कोई दो समवर्ती इकाइयां एक ही फ़ाइल नहीं लिखतीं; साझा फ़ाइलों (बैरेल, रजिस्ट्री, रूट टेबल) को एक मालिक मिलता है या एकीकरण के लिए इंतजार करना पड़ता है। कई इकाइयों पर निर्भर इंटरफेस परिवर्तन पहले आते हैं, अपनी खुद की इकाई के रूप में।
6. **परिणाम मापें।** शुरू करने से पहले एक प्रतिनिधि परिवर्तन चुनें और गिनें कि इसे करने के लिए पाठक को कितनी फ़ाइलें और पंक्तियाँ लोड करनी पड़ती हैं; फिर से गिनें। निर्यात किए गए नाम और कुल पंक्तियाँ गिरनी चाहिए या स्थिर रहनी चाहिए। एक पुनर्गठन जो इंटरफेस जोड़ता है, उसे एक स्पष्ट कारण देना चाहिए।
7. **रुकें** जब जो बचा हो वह ठंडा, आवश्यक, या एक तुकांत हो।
संबंधित कौशल, जहां उपलब्ध हों: `repo-review` (डिज़ाइन प्रकार) केवल सलाह के लिए जनगणना बनाता है; `design-cleanup` आकस्मिक जटिलता के लिए फिक्स-एंड-रीस्कैन लूप चलाता है; `context-audit` एंकर और कोडमैप जोड़ता है; `ousterhout-build-deep` एजेंट्स के लिए लेखक-समय चेकलिस्ट है जो इकाइयां कर रहे हैं।
## यह कहाँ बैठता है
यह कौशल समीक्षा और निर्णय परत है: इसका उपयोग यह तय करने के लिए करें कि कोई अमूर्तता गहरी है, सही निर्णय के लिए नामित है, और निकालने लायक है। `find-shared-code` इसका उपयोग प्रवेश परीक्षा के रूप में करता है जब हाल के इतिहास में साझा करने योग्य कोड की खोज करता है। नीचे दिया गया परिशिष्ट प्रत्येक लेखक की तर्क प्रक्रिया देता है।
---
## परिशिष्ट: गहराई से लेंस
प्रत्येक लेखक द्वारा पकड़ी गई विफलता मोड, और वह एक कदम जो वे आपको देते हैं। ऊपर की तालिका त्वरित संदर्भ है; यह इसके पीछे की तर्क प्रक्रिया है।
### Ousterhout — गहरे मॉड्यूल (रीढ़)
*एक सॉफ़्टवेयर डिज़ाइन का दर्शन।*
- **गहराई** = लाभ (छुपाई गई कार्यक्षमता) ÷ लागत (इंटरफेस जटिलता)। एक गहरा मॉड्यूल थोड़ा छुपाते हुए बहुत कुछ छुपाता है। एक सतही मॉड्यूल का इंटरफेस लगभग उसकी बॉडी जितना जटिल होता है, इसलिए यह कुछ भी कमाता नहीं।
- **जटिलता** सिस्टम की कोई भी ऐसी बात है जो इसे समझना या संशोधित करना कठिन बनाती है। दो स्रोत:
- **निर्भरता** — आप एक भाग को बदले बिना दूसरे को नहीं बदल सकते।
- **अस्पष्टता** — महत्वपूर्ण जानकारी कोड से स्पष्ट नहीं होती।
- **लक्षण:** परिवर्तन वृद्धि (एक निर्णय, कई संपादन), संज्ञानात्मक भार (आपको अपने सिर में कितना रखना पड़ता है), अज्ञात अज्ञात (आप नहीं बता सकते कि कोई परिवर्तन किस कोड को प्रभावित करेगा)।
- **मुख्य कदम:** जटिलता को *नीचे* खींचें — मॉड्यूल कठिन मामले को अवशोषित करता है ताकि कॉलर्स को न करना पड़े। कॉन्फ़िगरेशन पैरामीटर और पास-थ्रू कॉलर की ओर जटिलता *ऊपर* धकेलते हैं; यही सतहीपन है।
पकड़ता है: इंटरफेस जो अपनी कार्यान्वयन लीक करते हैं; हेल्पर्स जो मदद नहीं करते।
### Parnas — सूचना छुपाना (गहराई क्यों मायने रखती है)
*On the Criteria To Be Used in Decomposing Systems into Modules (1972).*
- **डिजाइन निर्णयों के आसपास विखंडन करें जो बदलने की संभावना रखते हैं**, न कि गणना के चरणों के आसपास। प्रत्येक मॉड्यूल एक ऐसा निर्णय छुपाता है।
- यह डीप मॉड्यूल का प्रत्यक्ष पूर्वज है। एक मॉड्यूल *डीप* इसलिए होता है क्योंकि यह ऐसा निर्णय छुपाता है जो अन्यथा कॉलर्स में फैल जाता।
पकड़: एक "मॉड्यूल" जो कुछ भी अस्थिर नहीं छुपाता — इसकी गहराई केवल सजावटी है। पूछें: इस इंटरफेस के पीछे क्या बदलता है जो कॉलर्स कभी नहीं देखते? यदि उत्तर "कुछ नहीं" है, तो सीमा केवल सजावट है।
### ब्रूक्स — आवश्यक बनाम आकस्मिक जटिलता
*कोई जादुई गोली नहीं।*
- **आवश्यक** जटिलता डोमेन में अंतर्निहित होती है (मूल्यांकन वास्तव में इतना जटिल है)। **आकस्मिक** जटिलता वह है जो हमारे उपकरण और संरचना थोपते हैं।
- केवल आकस्मिक जटिलता को हटाया जा सकता है। एक पुनर्गठन जो "साफ-सफाई" करता है केवल आवश्यक डोमेन जटिलता को एक फ़ाइल से दूसरी में स्थानांतरित करके, कुछ नहीं करता।
पकड़: सरलीकरण के रूप में छिपे पुनर्व्यवस्थापन। पूछें: क्या कुल जटिलता कम हुई, या केवल स्थानांतरित हुई?
### इवांस — डोमेन-ड्रिवन डिज़ाइन
*डोमेन-ड्रिवन डिज़ाइन।*
- सीमाओं को डोमेन की **सर्वव्यापी भाषा** में नामित किया जाना चाहिए, न कि सामान्य उपयोगिता शब्दों में। `helpers` नामक मॉड्यूल कुछ नामित नहीं करता; `AccessScope` या `PricingPolicy` नामक मॉड्यूल एक अपरिवर्तनीय नामित करता है।
- सीमित संदर्भ व्यापार अपरिवर्तनीयताओं को सीमाओं के पार लीक होने से रोकते हैं।
पकड़: सही विखंडन लेकिन अर्थहीन नाम। यदि आप मॉड्यूल को डोमेन भाषा में नाम नहीं दे सकते, तो संभवतः आपने सीमा गलत जगह काटी है।
### फाउलर — पुनर्गठन और कोड स्मेल्स
*पुनर्गठन।*
- वर्तमान डिज़ाइन से गहरे डिज़ाइन तक पहुंचने के लिए ठोस, सुरक्षित, नामित कदम (Extract Function, Move Field, Replace Conditional with Polymorphism) देता है।
- हर कदम व्यवहार-संरक्षित और छोटा होता है, इसलिए यह उलटनीय रहता है।
पकड़: "यह गहरा होना चाहिए" और अगली कमिट जानने के बीच का अंतर। ओस्टरहाउट लक्ष्य सेट करता है; फाउलर रास्ता।
### बेक — सरल डिज़ाइन, टेस्ट-फर्स्ट
*टेस्ट-ड्रिवन डेवलपमेंट; XP।*
- बेक के प्रकाशित क्रम में सरल डिज़ाइन के चार नियम: परीक्षण पास होना, कोई पुनरावृत्ति नहीं, इरादा प्रकट करना, न्यूनतम तत्व। यह प्रोग्राम बाद के फाउलर/हेन्स पुन:क्रमण का पालन करता है — पुनरावृत्ति से पहले इरादा — क्योंकि यह इस प्रोग्राम के Metz-विस्तारित अपरिवर्तनीय नियम की सेवा करता है (नीचे Metz देखें): पुनरावृत्ति पर तब तक कार्रवाई न करें जब तक आप उस इरादे का नाम न दे सकें जिसे यह संरक्षित करता है।
- टेस्ट-फर्स्ट पूर्व समय की वास्तुकला के खिलाफ ब्रेक है। पहले इसे काम करें और व्यवहार साबित करें, फिर उस सीम को गहरा करें जिसे अब परीक्षण संरक्षित करता है।
पकड़: व्यवहार पिन होने से पहले बनाई गई वास्तुकला। वर्तमान व्यवहार को साबित करने वाला कोई परीक्षण न होने पर, "गहरा करने" वाला पुनर्गठन एक अप्रमाणित पुनर्लेखन है।
### हिकी — सरल बनाम आसान
*Simple Made Easy.*
- **सरल** = बिना उलझे: एक अवधारणा, अन्य के साथ उलझी नहीं (वस्तुनिष्ठ)।
- **आसान** = पास में, परिचित, जल्दी पहुंचने योग्य (आपके सापेक्ष)।
- दोनों स्वतंत्र हैं। एक सतही सहायक आमतौर पर *आसान* होता है — लिखने में तेज़, पास में — लेकिन यदि यह असंबंधित चिंताओं को उलझाता है तो *सरल* नहीं होता।
पकड़: सुविधा को डिज़ाइन के रूप में प्रस्तुत करना। ऐसे निर्माण पसंद करें जो अवधारणाओं को उलझाए बिना रखें, भले ही उलझा हुआ टाइप करने में तेज़ हो।
### Metz — गलत अमूर्तता से बेहतर पुनरावृत्ति
*"The Wrong Abstraction" (2016)।*
- गलत अमूर्तता की तुलना में पुनरावृत्ति बहुत सस्ती है। बहुत जल्दी निकाली गई अमूर्तता हर भविष्य के कॉलर को उन मान्यताओं के चारों ओर झुकने के लिए मजबूर करती है जो सभी के लिए कभी सही नहीं थीं।
- जब अमूर्तता गलत साबित होती है, तो Metz का उपाय इसे वापस इनलाइन करना और पुनरावृत्ति को लौटने देना है, बजाय इसे उस मामले के लिए फिट करने के लिए मोड़ने के जिसके लिए यह कभी नहीं बनाई गई थी।
- **इस प्रोग्राम का नियम, Metz का विस्तार: कोड दोहराव के कारण केंद्रीकृत न करें। केंद्रीकृत करें जब यह एक वास्तविक, साझा अपरिवर्तनीय की रक्षा करता हो।** जब तक अपरिवर्तनीय प्रकट न हो, पुनरावृत्ति सहन करें।
पकड़: अत्यधिक केंद्रीकरण — सतही साझा सहायक जिसे अब हर कोई काम करना पड़ता है। यह यांत्रिक "DRY हर कीमत पर" का प्रतिपक्ष है।
### हायरम का नियम — प्रेक्षित व्यवहार अनुबंध बन जाता है
*"पर्याप्त उपयोगकर्ताओं की संख्या के साथ, आपके सिस्टम का हर प्रेक्षित व्यवहार किसी न किसी द्वारा निर्भर किया जाएगा।"*
- जो कुछ भी एक इंटरफेस *होता है* — क्रम, समय, त्रुटि पाठ — अंततः कोई उस पर निर्भर करेगा। इसलिए आप जो सतह दिखाते हैं वह उस सतह से बड़ी होती है जिसे आपने दस्तावेजीकृत किया।
- यह ओस्टरहाउट की **छोटी, स्थिर इंटरफेस** की प्राथमिकता का समर्थन करता है: जितना कम आप प्रकट करेंगे, उतना कम दुर्घटनावश भार वहन करने वाला बन सकता है।
पकड़: व्यापक इंटरफेस जो कठोर हो जाएंगे। हर अतिरिक्त प्रेक्षित भविष्य का प्रतिबंध बन जाता है।
### वे कैसे मेल खाते हैं
- **Parnas → Ousterhout:** अस्थिर निर्णय छुपाएं → मॉड्यूल गहरा होता है।
- **Brooks:** पुष्टि करें कि गहराई ने जटिलता को हटाया, केवल स्थानांतरित नहीं किया।
- **Evans:** सीमा को डोमेन भाषा में नामित करें।
- **Beck → Fowler:** व्यवहार पिन करें, फिर छोटे सुरक्षित कदमों में पुनर्गठन करें।
- **Metz:** तब तक केंद्रीकरण का विरोध करें जब तक अपरिवर्तनीय वास्तविक न हो।
- **Hickey:** इंटरफेस को एक अवधारणा तक सीमित रखें।
- **Hyrum:** उस इंटरफेस को छोटा रखें ताकि वह स्थिर रह सके।
खतरा है कि ओस्टरहाउट को SOLID या Clean Code की यांत्रिक व्याख्या के साथ मिलाना: इससे कई छोटे क्लास और फंक्शन बनते हैं जिनके सतही इंटरफेस होते हैं — जो गहरे मॉड्यूल के बिल्कुल विपरीत है। ओस्टरहाउट, Metz के प्रतिपक्ष के साथ, इसका समाधान है।
टैग
और जानें
Claude Ads: वह Claude Code स्किल जो आपके विज्ञापन अकाउंट का ऑडिट करती है
Claude Ads, Claude Code के लिए एक ओपन-सोर्स स्किल है: Google, Meta, LinkedIn, TikTok या Amazon Ads पर 250 से ज़्यादा जाँचें, 100 में से एक स्कोर और प्राथमिकता के हिसाब से बनी एक्शन प्लान, वो भी करीब दस मिनट में। इंस्टॉलेशन, कमांड, सीमाएँ, और इसे AgentsRoom में कैसे चलाएँ।
AGENTS.md: हर coding agent के लिए एक ही context file (Codex, Antigravity, Claude)
AGENTS.md वह portable instructions file है जिसे आपके AI coding agents आपके code को छूने से पहले पढ़ते हैं। इसमें क्या डालें, यह CLAUDE.md से कैसे अलग है, और Codex, Antigravity और Claude के बीच एक ही context कैसे बनाए रखें।
AgentsRoom डाउनलोड करें
अपने सभी AI एजेंट्स को, अपने सभी प्रोजेक्ट्स पर, एक ही विंडो से चलाएं।
कंपेनियन ऐप: चलते-फिरते अपने एजेंट्स मॉनिटर करें
Claude, Codex, Antigravity CLI या किसी अन्य AI प्रदाता का उपयोग करें।
बग और अनुरोध सीधे अपने सार्वजनिक बैकलॉग में भेजें।