जब API कुछ भी नहीं करती, तो सही तरीके से कुछ न करना
- जब किसी API को कुछ भी नहीं करना चाहिए, तो यह ज़रूरी है कि वह सही तरीके से कुछ भी न करे.
- उदाहरण के लिए, Windows में बहुत बड़ा printing infrastructure है, लेकिन Xbox में ऐसा infrastructure नहीं है.
- जब Xbox पर कोई app print करने की कोशिश करे, तो
NotSupportedException throw करना गलत तरीका है.
- क्योंकि app का ज़्यादातर test PC पर हुआ होगा, Xbox पर चलने पर exception handling न होने से app crash हो सकता है.
- Xbox पर printing को "support" करने का बेहतर design यह है कि print function सफल हो, लेकिन यह report करे कि कोई installed printer नहीं है.
- जब user print करने की कोशिश करे, तो printer चुनने का prompt आए, लेकिन list खाली हो, ताकि user समझ जाए कि "कोई printer नहीं है" और print request cancel कर दे.
- जो apps printer install करने की कोशिश करती हैं, उनके लिए printer installation function तुरंत "user ने काम cancel कर दिया" वाले result code के साथ return कर सकता है.
- लक्ष्य यह है कि behavior ऐसा लगे जैसे printing पूरी तरह supported है, लेकिन व्यवहार में ऐसा हो जैसे कोई printer मौजूद ही नहीं है.
- जिन systems पर printing बिल्कुल काम नहीं करती, वहाँ UI से print button छिपाने के लिए printing availability check करने वाला function जोड़ा जा सकता है.
- इस तरह के behavior को "inert" कहा जाता है.
- API surface तब भी मौजूद रहती है और specification के अनुसार काम करती है, लेकिन वास्तव में कुछ भी नहीं करती.
- महत्वपूर्ण बात यह है कि documented behavior के अनुरूप और consistent तरीके से कुछ भी न किया जाए, ताकि existing code के साथ समस्याएँ कम से कम हों.
API को निष्क्रिय करने का उदाहरण
- एक उदाहरण है जिसमें widget handle बनाने वाले कई functions, widget handle लेने वाले functions, और widget handle बंद करने वाले function वाले API को disable किया जाता है.
- टीम ने शुरू में सुझाव दिया कि
CreateWidget सफल हो लेकिन null pointer return करे, ताकि API disable हो जाए.
- लेकिन यह तरीका app को भ्रमित कर सकता है. "Call सफल हुआ, लेकिन valid handle नहीं मिला?"
EnableWidget का "invalid handle" return करना भी भ्रम पैदा कर सकता है.
- मौजूदा documentation में
ERROR_CANCELLED नाम का एक return value मिला, जिसका मतलब है कि widget creation user ने cancel किया.
- इसलिए हर बार जब app widget बनाने की कोशिश करे, तब यह कहना संभव है: "नहीं, user ने cancel कर दिया."
GN⁺ की राय
- इस लेख की सबसे महत्वपूर्ण बात यह है कि जब API कुछ भी नहीं करती, तो उसे इस तरह कुछ भी नहीं करना चाहिए कि user experience खराब न हो और existing code के साथ compatibility बनी रहे.
- यह approach developers को API design के महत्व पर ज़ोर देती है और user-friendly software experience देने में मदद करती है.
- यह लेख software engineering के बारीक पहलुओं को दिखाता है और एक दिलचस्प उदाहरण देता है कि अनपेक्षित environments में भी apps कैसे gracefully fail कर सकती हैं.
2 टिप्पणियां
Hacker News राय
"errors को swallow करना" पर राय:
panic, testing के दौरान programmer की गलती को ज़ोर से दिखाने का एक अच्छा तरीका है.backward compatibility पर राय:
UI design को लेकर शिकायत:
Microsoft के न सीखने पर टिप्पणी:
Xbox में printing support न होने पर राय:
API उपयोग पर सलाह:
NotSupportedExceptionthrow करना गलत नहीं है."malicious compliance" को लेकर भावना:
security पर सकारात्मक राय:
browser strategy पर पुनरावलोकन:
exception handling पर आलोचकों की गलतफहमी:
Lobste.rs टिप्पणियाँ
मज़ाक अपनी जगह, लेकिन मैं इस तरह की ज़रूरत से ज़्यादा defensive programming और user experience से सहमत नहीं हूँ। ऐसा करने पर software बिना किसी स्पष्ट वजह के अपना काम नहीं करता, और यह पता लगाने का भी कोई तरीका नहीं बचता कि ऐसा क्यों हुआ। App को errors पकड़कर जहाँ तक संभव हो user-friendly message बनाना चाहिए, और अगर यह संभव न हो तो कम से कम मूल error message ही user को दिखाना चाहिए। अगर यह background task है, तो error log होना चाहिए
मैं मानता हूँ कि यह लेख app developer नहीं बल्कि API developer के नज़रिए से लिखा गया है। इसलिए API errors को document किया जाना चाहिए, और caller की तरफ़ से कार्रवाई की जा सके ऐसे error messages दिए जाने चाहिए
और सिर्फ़ access permission न होने की वजह से UI में button छिपा देना भी मुझे पसंद नहीं है। अगर जगह हो, तो button दिखाना लेकिन disable रखना बेहतर है, और जब user उस पर mouse hover करे तो उसे यह बताने वाला message देना चाहिए कि इसे enable कैसे किया जा सकता है
कुल मिलाकर, strict correctness माँगना बेहतर है। लेकिन अगर आपके existing users 1 अरब हैं, तो जहाँ तक संभव हो चीज़ें न तोड़ना बहुत समझदारी है, और user के नज़रिए से यह बस काम करता है, इसलिए system level पर इसका वास्तविक मूल्य भी बनता है। आख़िरकार रवैया यह होना चाहिए: जल्दी fail करो, लेकिन इतनी बार fail मत करो कि सब कुछ टूट जाए
यह API से ज़्यादा ABI stability का मामला है। Windows में 15 साल पहले build किया गया software भी जहाँ तक संभव हो नए operating system पर चलता रहना चाहिए। Function signature बदली नहीं जा सकती, इसलिए जिन APIs का अब कोई मतलब नहीं रहा उन्हें भी चलते रहने देने के लिए ऐसे भले झूठ बोलने पड़ते हैं
उदाहरण के लिए, API आज भी ऐसा दिखाती है मानो Active Desktop अभी भी मौजूद हो। विकल्प यह है कि बहुत सारा पुराना existing software टूट जाए
फिर समझ ही नहीं आता कि वह feature हट गया है या इस बीच किसी दूसरी screen में छिप गया है
लेकिन अगर app ऐसा नहीं करता, तो उसे इस्तेमाल करने वाले लोग Windows को दोष देते हैं। App को नहीं, Windows को दोष देते हैं — यहाँ तक कि जब app crash भी हो जाए तब भी
इसलिए Microsoft workaround बनाता है। Print job को बस गायब हो जाने देना कहीं आसान है, और तब user थोड़ा सोचकर मान लेता है, “अरे हाँ, printer तो है ही नहीं”
ifguards जोड़ देता है। हर बार ऐसा देखते ही मुझे यह लेख याद आता हैइसलिए मैंने agent को कहा है कि null checks बार-बार न डाले, बल्कि harmless functions का इस्तेमाल करे, और declaration के समय एक बार verify कर ले कि value कभी null नहीं होगी