क्या jQuery "देव वस्तु" प्रतिपदा का उदाहरण है?


56

मैं पूछना चाहता हूं - मैं धीरे-धीरे jQuery सीख रहा हूं।

मैं जो देखता हूं वह एक ईश्वर वस्तु विरोधी पैटर्न का सटीक उदाहरण है । मूल रूप से, सब कुछ फ़ंक्शन पर जाता है , चाहे वह कुछ भी हो।$

क्या मैं सही हूं और jQuery वास्तव में इस विरोधी पैटर्न का एक उदाहरण है?


13
आप शायद गलत सवाल पूछ रहे हैं। सही सवाल यह है, "जावास्क्रिप्ट को कैसे जावास्क्रिप्ट भाषा में इस तरह से लागू किया जा सकता है, जिसमें $फ़ंक्शन या jQueryऑब्जेक्ट की आवश्यकता न हो ।
रॉबर्ट हार्वे

1
मैं हमेशा से यह सवाल पूछना चाहता था :)।
AnyOne

@RobertHarvey: दुख की बात है कि मुझे इसका जवाब देने के लिए जावास्क्रिप्ट के बारे में पर्याप्त जानकारी नहीं है।
कारेल बिलेक

हां (12 और चरित्र जाने के लिए ...)
एंड्रिया

यह एक सुधारात्मक पुस्तकालय की तरह है
एंड्रयू

जवाबों:


54

उस प्रश्न का उत्तर देने के लिए, मैं आपसे एक अन्य संरचना के बारे में एक विवेचनात्मक प्रश्न पूछने जा रहा हूं जिसमें DOM तत्वों के समान गुण है जो jQuery में हेरफेर करता है, वह अच्छा पुराना पुनरावृत्ति है। प्रश्न है:

एक साधारण पुनरावृत्ति पर आपको कितने ऑपरेशन की आवश्यकता है?

इस प्रश्न का उत्तर किसी भी भाषा में किसी भी Iterator API को देखकर आसानी से दिया जा सकता है। आपको 3 तरीके चाहिए:

  1. वर्तमान मूल्य प्राप्त करें
  2. अगले तत्व में पुनरावृत्ति ले जाएँ
  3. जाँच करें कि क्या Iterator में अधिक तत्व हैं

बस इतना ही चाहिए। यदि आप उन 3 कार्यों को कर सकते हैं, तो आप तत्वों के किसी भी क्रम को गर्त में ले जा सकते हैं।

लेकिन यह केवल वह नहीं है जो आप आमतौर पर तत्वों के अनुक्रम के साथ करना चाहते हैं, क्या यह है? आपके पास आमतौर पर एक उच्च स्तर का लक्ष्य प्राप्त करना होता है। आप हर तत्व के साथ कुछ करना चाह सकते हैं, आप उन्हें कुछ शर्त, या कई अन्य तरीकों में से एक के अनुसार फ़िल्टर करना चाह सकते हैं। अधिक उदाहरणों के लिए .NET में आईनेक्यू लाइब्रेरी में IEnumerable इंटरफ़ेस देखें ।

क्या आप देखते हैं कि कितने हैं? और यह सिर्फ उन सभी तरीकों का एक सबसेट है जो वे IEnumerable इंटरफ़ेस पर रख सकते थे, क्योंकि आप आमतौर पर उन्हें और भी उच्च लक्ष्य प्राप्त करने के लिए संयोजित करते हैं।

लेकिन यहाँ ट्विस्ट है। वे तरीके IEnumerable इंटरफ़ेस पर नहीं हैं। वे सरल उपयोगिता विधियां हैं जो वास्तव में IEnumerable को इनपुट के रूप में लेते हैं और इसके साथ कुछ करते हैं। तो जबकि C # भाषा में ऐसा लगता है कि IEnumerable इंटरफ़ेस पर एक bajillion विधियाँ हैं, IEnumerable एक देव वस्तु नहीं है।


अब वापस jQuery के लिए। आइए इस प्रश्न को फिर से पूछें, इस बार DOM तत्व के साथ।

DOM तत्व पर आपको कितने ऑपरेशन की आवश्यकता है?

फिर से जवाब बहुत सीधा है। आपके लिए आवश्यक सभी विधियाँ विशेषताओं और बाल तत्वों को पढ़ने / संशोधित करने की विधियाँ हैं। यह इसके बारे में। बाकी सब चीजें केवल उन बुनियादी कार्यों का एक संयोजन है।

लेकिन आप डोम तत्वों के साथ कितना उच्च स्तर का सामान लेना चाहेंगे? खैर, एक Iterator के रूप में ही: एक bajillion अलग बातें। और यही वह जगह है जहाँ jQuery आता है। jQuery, संक्षेप में दो चीजें प्रदान करता है:

  1. उपयोगिताओं के तरीकों का एक बहुत अच्छा संग्रह जिसे आप DOM तत्व पर कॉल करना चाहते हैं, और;
  2. सिंथेटिक चीनी ताकि मानक डोम एपीआई का उपयोग करने की तुलना में इसका उपयोग करना बेहतर अनुभव हो।

यदि आप शक्करयुक्त रूप लेते हैं, तो आपको पता चलता है कि jQuery को आसानी से DOM तत्वों का चयन किया जा सकता है जो DOM तत्वों का चयन / संशोधन करते हैं। उदाहरण के लिए:

$("#body").html("<p>hello</p>");

... के रूप में लिखा जा सकता था:

html($("#body"), "<p>hello</p>");

शब्दशः यह एक ही बात है। हालांकि पहले फॉर्म का बड़ा फायदा यह है कि बयानों के बाएं-दाएं क्रम को उन कार्यों का पालन किया जाता है, जिन्हें संचालन निष्पादित किया जाएगा। बीच में दूसरी शुरुआत, जो कोड को पढ़ने के लिए बहुत कठिन बनाता है यदि आप बहुत सारे ऑपरेशनों को एक साथ जोड़ते हैं।

तो इस सबका क्या मतलब है? वह jQuery (जैसे LINQ) ईश्वर वस्तु विरोधी पैटर्न नहीं है। इसके बजाय यह एक बहुत सम्मानित पैटर्न का मामला है जिसे डेकोरेटर कहा जाता है ।


लेकिन फिर, $उन सभी अलग-अलग चीजों को करने के ओवरराइड के बारे में क्या ? ठीक है, यह सिर्फ वाक्यात्मक चीनी है। सभी कॉल्स $और इसके डेरिवेटिव्स की तरह $.getJson()पूरी तरह से अलग चीजें हैं जो सिर्फ इसी तरह के नामों को साझा करने के लिए होती हैं ताकि आप तुरंत महसूस कर सकें कि वे jQuery के हैं। $एक और केवल एक कार्य करता है: आपको jQuery का उपयोग करने के लिए एक आसानी से पहचानने योग्य प्रारंभिक बिंदु है। और उन सभी विधियों को जिन्हें आप jQuery ऑब्जेक्ट पर कॉल कर सकते हैं, वे एक ईश्वर ऑब्जेक्ट का लक्षण नहीं हैं। वे बस अलग-अलग उपयोगिता कार्य करते हैं जो प्रत्येक एक डोम तत्व पर एक और केवल एक तर्क के रूप में पारित करते हैं। .Dot संकेतन केवल यहाँ है क्योंकि यह लेखन कोड को आसान बनाता है।


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

2
@RossPatterson क्या आप असहमत हैं? यदि आप हैं, तो मैं आपको अपना उत्तर पोस्ट करने के लिए प्रोत्साहित करूंगा। मुझे लगता है कि लॉरेंट अच्छा है, लेकिन मैं अभी भी अनिर्दिष्ट हूं।
निकोल

@RossPatterson मुझे लगता है अपनी टिप्पणी का मतलब यह है कि यह एक मामले में जहां यह है कि है एक भगवान वस्तु लेकिन यह एक अच्छी बात है। क्या मैं गलत हूं?
लॉरेंट बॉरगुल-रॉय

3
@ LaurentBourgault-Roy मैं आपके निष्कर्ष से असहमत हूं - मेरा मानना ​​है कि jQuery वास्तव में एक ईश्वर वस्तु उदाहरण है। लेकिन आपने इतना अच्छा काम किया कि मैं आपके जवाब को नहीं मान सकता। अपनी स्थिति के एक महान विवरण के लिए धन्यवाद।
रॉस पैटरसन

1
मैं सहमति से पूरी तरह असहमत हूं। JQuery पर कई उपयोगिता कार्य हैं जो DOM मैनिपुलेशन से संबंधित नहीं हैं।
बोरिस यानकोव

19

नहीं - $फ़ंक्शन वास्तव में केवल तीन कार्यों के लिए अतिभारित है । बाकी सब कुछ बाल कार्य हैं जो इसे एक नामस्थान के रूप में उपयोग करते हैं ।


17
लेकिन यह एक " jQuery " ऑब्जेक्ट देता है, जिसमें jQuery API का बहुत हिस्सा होता है - और, मुझे लगता है, ओपी की बात करते हुए "भगवान" ऑब्जेक्ट होगा।
निकोल

2
@NickC, भले ही यह एक वस्तु है, उस मामले में मुझे लगता है कि यह वास्तव में नाम की तरह उपयोग किया जाता है, जैसे Math। चूंकि JS में कोई बिल्ड-इन नाम स्थान नहीं है, इसलिए वे इसके लिए किसी ऑब्जेक्ट का उपयोग करते हैं। हालांकि मुझे यकीन नहीं है कि विकल्प क्या होगा? सभी कार्यों और गुणों को वैश्विक नामस्थान में रखें?
लौरेंट

5

मुख्य jQuery फ़ंक्शन (जैसे $("div a")) अनिवार्य रूप से एक कारखाना विधि है जो jQuery प्रकार का एक उदाहरण देता है जो DOM तत्वों के संग्रह का प्रतिनिधित्व करता है।

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

अंत में, माइकल बोर्गवर्ड के रूप में उल्लेख किया गया है कि बड़ी संख्या में उपयोगिता फ़ंक्शंस भी हैं जो $ नाम के रूप में उपयोग करते हैं और केवल DOM संग्रह jQuery ऑब्जेक्ट्स से संबंधित हैं।


1
यह ईश्वर ऑब्जेक्ट पैटर्न में क्यों फिट नहीं है?
बेंजामिन हॉजसन

4

$ कोई वस्तु नहीं है, यह एक नाम स्थान है।

क्या आप java.lang को एक देव वस्तु कहेंगे क्योंकि इसमें कई वर्ग शामिल हैं? यह कॉल करने के लिए बिल्कुल वैध वाक्यविन्यास है java.lang.String.format(...), जो कि jQuery पर कॉल करने के लिए बहुत समान है।

एक वस्तु, एक देव वस्तु होने के लिए, पहले स्थान पर एक उचित वस्तु होना चाहिए - जिसमें डेटा और डेटा पर कार्य करने के लिए खुफिया दोनों शामिल हैं। jQuery में केवल विधियाँ सम्‍मिलित हैं।

इसे देखने का एक और तरीका है: किसी वस्तु का किसी देव वस्तु का कितना अच्छा सामंजस्य है, इसके लिए एक अच्छा उपाय है - कम सामंजस्य का अर्थ है किसी देव वस्तु का अधिक होना। सामंजस्य का कहना है कि डेटा का बहुत अधिक उपयोग कितने तरीकों से किया जाता है। चूँकि jQuery में कोई डेटा नहीं है, आप गणित करते हैं - सभी विधियाँ सभी डेटा का उपयोग करती हैं, इसलिए jQuery अत्यधिक सामंजस्यपूर्ण है, इस प्रकार एक देव वस्तु नहीं है।


3

बेंजामिन ने मुझे अपनी स्थिति स्पष्ट करने के लिए कहा, इसलिए मैंने अपनी पिछली पोस्ट को संपादित किया और आगे के विचार जोड़े।

बॉब मार्टिन क्लीन कोड के रूप में एक महान पुस्तक के लेखक हैं। उस पुस्तक में वस्तुओं और डेटा संरचनाओं नामक एक अध्याय (अध्याय 6.) है, जिसमें वह वस्तुओं और डेटा संरचनाओं के बीच सबसे महत्वपूर्ण अंतरों पर चर्चा करता है और दावा करता है कि हमें उनके बीच चयन करना है, क्योंकि उन्हें मिश्रण करना एक बहुत बुरा विचार है।

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

मुझे लगता है कि DOM इन ऑब्जेक्ट और डेटा संरचना संकर का एक उदाहरण है। उदाहरण के लिए DOM द्वारा हम इस तरह कोड लिखते हैं:

el.appendChild(node);
el.childNodes;
// bleeding internals

el.setAttribute(attr, val);
el.attributes;
// bleeding internals

el.style.color;
// at least this is okay

el = document.createElement(tag);
doc = document.implementation.createHTMLDocument();
// document is both a factory and a tree root

डोम स्पष्ट रूप से एक हाइब्रिड के बजाय एक डेटा संरचना होना चाहिए।

el.childNodes.add(node);
// or el.childNodes[el.childNodes.length] = node;
el.childNodes;

el.attributes.put(attr, val);
// or el.attributes[attr] = val;
el.attributes;

el.style.get("color"); 
// or el.style.color;

factory = new HtmlNodeFactory();
el = factory.createElement(document, tag);
doc = factory.createDocument();

JQuery फ्रेमवर्क प्रक्रियाओं का एक समूह है, जो DOM नोड्स के संग्रह को चुन और संशोधित कर सकता है और कई अन्य काम कर सकता है। जैसा कि लॉरेंट ने अपने पोस्ट में बताया, jQuery कुछ इस तरह से हुड के नीचे है:

html(select("#body"), "<p>hello</p>");

JQuery के डेवलपर्स ने इन सभी प्रक्रियाओं को एक एकल वर्ग में विलय कर दिया, जो ऊपर सूचीबद्ध सभी सुविधाओं के लिए जिम्मेदार है। तो यह स्पष्ट रूप से एकल जिम्मेदारी सिद्धांत का उल्लंघन करता है और इसलिए यह एक देव वस्तु है। केवल एक चीज क्योंकि यह कुछ भी नहीं तोड़ता है, क्योंकि यह एक एकल स्टैंडअलोन वर्ग है जो एक एकल डेटा संरचना (डोम नोड्स का संग्रह) पर काम करता है। अगर हम jQuery के उपवर्ग या किसी अन्य डेटा संरचना को जोड़ते हैं, तो परियोजना बहुत तेज़ी से ध्वस्त हो जाएगी। इसलिए मुझे नहीं लगता कि हम jo द्वारा oo के बारे में बात कर सकते हैं यह इस तथ्य के बावजूद कि यह एक वर्ग को परिभाषित करता है के बावजूद oo की तुलना में प्रक्रियात्मक है।

लॉरेंट क्या दावा करता है एक पूरी बकवास है:

तो इस सबका क्या मतलब है? वह jQuery (जैसे LINQ) ईश्वर वस्तु विरोधी पैटर्न नहीं है। इसके बजाय यह एक बहुत सम्मानित पैटर्न का मामला है जिसे डेकोरेटर कहा जाता है।

डेकोरेटर पैटर्न इंटरफ़ेस को बनाए रखने और मौजूदा कक्षाओं को संशोधित नहीं करके नई कार्यक्षमता जोड़ने के बारे में है। उदाहरण के लिए:

आप 2 वर्गों को परिभाषित कर सकते हैं जो समान इंटरफ़ेस को लागू करते हैं, लेकिन पूरी तरह से अलग कार्यान्वयन के साथ:

/**
 * @interface
 */
var Something = function (){};
/**
 * @argument {string} arg1 The first argument.
 * @argument {string} arg2 The second argument.
 */
Something.prototype.doSomething = function (arg1, arg2){};

/**
 * @class
 * @implements {Something}
 */
var A = function (){
    // ...
};
/**
 * @argument {string} arg1 The first argument.
 * @argument {string} arg2 The second argument.
 */
A.prototype.doSomething = function (arg1, arg2){
    // doSomething implementation of A
};

/**
 * @class
 * @implements {Something}
 */
var B = function (){
    // ...
};
/**
 * @argument {string} arg1 The first argument.
 * @argument {string} arg2 The second argument.
 */
B.prototype.doSomething = function (arg1, arg2){
    // doSomething implementation of B
    // it is completely different from the implementation of A
    // that's why it cannot be a sub-class of A
};

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

/**
 * @class
 * @implements {Something}
 * @argument {Something} something The decorated object.
 */
var SomethingDecorator = function (something){
    this.something = something;
    // ...
};

/**
 * @argument {string} arg1 The first argument.
 * @argument {string} arg2 The second argument.
 */
SomethingDecorator.prototype.doSomething = function (arg1, arg2){
    return this.something.doSomething(arg1, arg2);
};

/**
 * A new method which can be common by A and B. 
 * 
 * @argument {function} done The callback.
 * @argument {string} arg1 The first argument.
 * @argument {string} arg2 The second argument.
 */
SomethingDecorator.prototype.doSomethingDelayed = function (done, arg1, arg2){
    var err, res;
    setTimeout(function (){
        try {
            res = this.doSomething(o.arg1, o.arg2);
        } catch (e) {
            err = e;
        }
        callback(err, res);
    }, 1000);
};

तो आप मूल उदाहरणों को उच्च अमूर्त स्तर कोड में डेकोरेटर उदाहरणों के साथ स्थानापन्न कर सकते हैं।

function decorateWithManyFeatures(something){
    var d1 = new SomethingDecorator(something);
    var d2 = new AnotherSomethingDecorator(d1);
    // ...
    return dn;
}

var a = new A();
var b = new B();
var decoratedA = decorateWithManyFeatures(a);
var decoratedB = decorateWithManyFeatures(b);

decoratedA.doSomethingDelayed(...);
decoratedB.doSomethingDelayed(...);

यह निष्कर्ष कि jQuery किसी भी चीज़ का डेकोरेटर नहीं है, क्योंकि यह Array, NodeList या किसी अन्य DOM ऑब्जेक्ट के समान इंटरफ़ेस को लागू नहीं करता है। यह अपने स्वयं के इंटरफ़ेस को लागू करता है। मॉड्यूल को सज्जाकार के रूप में भी उपयोग नहीं किया जाता है, वे बस मूल प्रोटोटाइप को ओवरराइड करते हैं। तो डेकोरेटर पैटर्न का उपयोग पूरे jQuery लिब में नहीं किया जाता है। JQuery वर्ग बस एक विशाल एडॉप्टर है जो हमें कई अलग-अलग ब्राउज़रों द्वारा एक ही एपीआई का उपयोग करने देता है। ऊ के नजरिए से यह पूरी तरह गड़बड़ है, लेकिन यह वास्तव में मायने नहीं रखता है, यह अच्छी तरह से काम करता है, और हम इसका उपयोग करते हैं।


आप तर्क दे रहे हैं कि ओफ़ कोड और प्रक्रियात्मक कोड के बीच इन्फिक्स विधियों का उपयोग महत्वपूर्ण है। मुझे नहीं लगता कि यह सच है। क्या आप अपनी स्थिति स्पष्ट कर सकते हैं?
बेंजामिन हॉजसन

@BenjaminHodgson "इन्फिक्स विधि" के तहत आपका क्या मतलब है?
inf3rno

@BenjaminHodgson मैंने स्पष्ट किया। मुझे उम्मीद है कि अब यह स्पष्ट है।
inf3rno
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.