2008-10-22 11 views
9

मैं सीखने की कोशिश कर रहा हूं कि मौजूदा कोड में परीक्षण कैसे जोड़ना है - वर्तमान में Working Effectively With Legacy Code पढ़ना पढ़ना। मैं जावास्क्रिप्ट में कुछ सिद्धांतों को लागू करने की कोशिश कर रहा हूं, और अब मैं एक इंटरफेस निकालने की कोशिश कर रहा हूं।क्या जावास्क्रिप्ट में विरासत करने का कोई "सही" तरीका है? यदि ऐसा है, तो ये क्या है?

जावास्क्रिप्ट में इंटरफेस बनाने के लिए खोज में, मुझे बहुत कुछ नहीं मिल रहा है - और मुझे विरासत के बारे में जो कुछ मिलता है वह उनके कई अलग-अलग तरीकों से लगता है। (कुछ लोग अपनी खुद की आधार कक्षाएं बनाते हैं ताकि वे विरासत को आसान बना सकें, कुछ उपयोग कार्यों, कुछ प्रोटोटाइप का उपयोग करें)।

सही तरीका क्या है? जावास्क्रिप्ट में एक इंटरफ़ेस निकालने के लिए एक सरल उदाहरण मिला?

उत्तर

13

कोई निश्चित सही तरीका है, क्योंकि बहुत से लोग इतनी सारी चीज़ें कर रहे हैं .. कई उपयोगी पैटर्न हैं।

क्रॉकफ़ोर्ड सुझाव देता है कि आप "अनाज के साथ जाएं", या जावास्क्रिप्ट की प्रोटोटाइप प्रकृति के अनुरूप जावास्क्रिप्ट लिखें।

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

उन्होंने "ऑब्जेक्ट" फ़ंक्शन को एक उपाय के रूप में लिखा (अब ऑब्जेक्ट.क्रेट() के रूप में जाना जाता है)। यह कुछ बहुत शक्तिशाली प्रोटोटाइप पैटर्न के लिए अनुमति देता है।

जब आप विरासत जावास्क्रिप्ट के साथ काम करना चाहते हैं तो एक साफ इंटरफ़ेस विकसित करना हमेशा आसान नहीं होता है, विशेष रूप से जब आप बड़े सिस्टम से निपटते हैं, आमतौर पर एकाधिक पुस्तकालयों सहित, और प्रत्येक एक अद्वितीय शैली और विभिन्न विरासत पैटर्न को लागू करते हैं। आम तौर पर, मैं कहूंगा कि विरासत करने का "सही तरीका" वह है जो आपको एक स्वच्छ इंटरफ़ेस लिखने की अनुमति देता है जो आपके विरासत कोड के संदर्भ में अच्छी तरह से व्यवहार करता है, लेकिन आपको समय के साथ पुरानी निर्भरताओं को पुन: सक्रिय करने और समाप्त करने की अनुमति देता है ।

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

इन पंक्तियों के साथ, मैंने इंटरफेस लिखा है जो क्रॉकफोर्ड के परजीवी विरासत पैटर्न से प्रेरित थे। यह सादगी के लिए वास्तव में एक जीत है।

सिक्का के दूसरी तरफ, मुझे यकीन है कि आप पुस्तकालय चुनने, इसे अपनी टीम में लागू करने और इसके विरासत पैटर्न और उसके इंटरफेस सम्मेलनों दोनों के अनुरूप होने के लिए बहस कर सकते हैं।

+2

कैसे कुछ लिंक के बारे में? – pc1oad1etter

3

डीन एडवर्ड्स बेस.जे.एस. भी देखें। आप इसे here पर देख सकते हैं, ब्लॉग पोस्ट स्वयं व्याख्यात्मक है।

5

आप दो अलग-अलग चीजों को देख रहे हैं।

सबसे पहले आपके पास इंटरफेस हैं। इसे कार्यान्वित करने का सबसे स्वीकार्य तरीका हालांकि डक टाइपिंग ("अगर यह एक बतख की तरह बतख और quacks की तरह दिखता है तो यह एक बतख है")। इसका अर्थ यह है कि यदि कोई ऑब्जेक्ट इंटरफ़ेस के तरीकों का एक सेट लागू करता है तो यह इंटरफ़ेस है। आप इंटरफेस को परिभाषित करने वाले विधि नामों की एक सरणी करके इसे कार्यान्वित करते हैं। फिर यह जांचने के लिए कि कोई ऑब्जेक्ट लागू करता है जो आपको इंटरफेस करता है, यह देखने के लिए कि क्या यह उन तरीकों को लागू करता है।यहां एक कोड उदाहरण है जिसे मैंने चाबुक किया:

function Implements(obj, inter) 
{ 
    var len = inter.length, i = 0; 
    for (; i < len; ++i) 
    { 
     if (!obj[inter[i]]) 
      return false; 
    } 
    return true; 
} 

var IUser = ["LoadUser", "SaveUser"]; 

var user = { 
     LoadUser : function() 
     { 
      alert("Load"); 
     }, 

     SaveUser : function() 
     { 
      alert("Save"); 
     } 
    }; 

var notUser = { 
     LoadUser : function() 
     { 
      alert("Load"); 
     } 
    }; 

alert(Implements(user, IUser)); 
alert(Implements(notUser, IUser)); 

अब आपके पास विरासत है। जेएस में कोई विरासत नहीं है; इसलिए आपको इसे मैन्युअल रूप से कार्यान्वित करना होगा। यह सिर्फ एक वस्तु के गुणों को "प्रतिलिपि" करने का मामला है। यहाँ एक और कोड नमूना है (सही नहीं है, लेकिन यह बात को दर्शाता है):

function InheritObject(base, obj) 
{ 
    for (name in base) 
    { 
     if (!obj[name]) 
      obj[name] = base[name]; 
    } 
} 

var Base = { 
     BaseFunc : function() { alert("BaseFunc from base"); }, 
     InheritFunc : function() { alert("InheritFunc from base"); } 
    } 

var Inherit = { 
     InheritFunc : function() { alert("InheritFunc from inherit"); }, 
     AnotherFunc : function() { alert("AnotherFunc from inherit"); } 
    } 

InheritObject(Base, Inherit); 

Inherit.InheritFunc(); 
Inherit.BaseFunc(); 
Inherit.AnotherFunc(); 

Base.BaseFunc(); 
Base.InheritFunc(); 

आप शायद http://www.mootools.net को देखने के लिए चाहते हैं। इसमें कक्षाओं का मेरा पसंदीदा कार्यान्वयन है। आप यह भी निश्चित रूप से "प्रो जावास्क्रिप्ट डिजाइन पैटर्न"

http://www.amazon.com/JavaScript-Design-Patterns-Recipes-Problem-Solution/dp/159059908X

इस किताब को कैसे जावास्क्रिप्ट में OOP का अनुकरण करने के बारे में अच्छा विस्तार में चला जाता है बाहर की जाँच करना चाहते हैं।

+0

+1 सरल और स्पष्ट स्पष्टीकरण! –

6

जावास्क्रिप्ट में केवल कोई वर्ग नहीं है, केवल ऑब्जेक्ट्स।
लेकिन अगर आप वर्ग आधारित वस्तु उन्मुख मॉडल की नकल पर जोर देते हैं तो आप इस का उपयोग कर सकते हैं:

 
function ChildClass() { 
    ParentClass.call(this); 
    // Write the rest of your constructor function after this point. 
}; 
ChildClass.prototype = jQuery.extend({}, ParentClass.prototype, ChildClass.prototype); 

jQuery.extend एक 'उथले प्रतिलिपि' jQuery पुस्तकालय से कार्य है। आप इसे किसी अन्य ऑब्जेक्ट कॉपीिंग/क्लोनिंग फ़ंक्शन के साथ प्रतिस्थापित कर सकते हैं।

+1

पहली वाक्य पर अधिक जोर नहीं दिया जा सकता है – Claudiu

0

प्रोटोटाइप http://www.prototypejs.org/api/class/create से, विरासत पर अपना ले प्रदान करता है:

var Animal = Class.create({ 
    initialize: function(name, sound) { 
    this.name = name; 
    this.sound = sound; 
    }, 

    speak: function() { 
    alert(this.name + " says: " + this.sound + "!"); 
    } 
}); 

// subclassing Animal 
var Snake = Class.create(Animal, { 
    initialize: function($super, name) { 
    $super(name, 'hissssssssss'); 
    } 
}); 
संबंधित मुद्दे