Pratik javascript nesne yönelimli tasarım modellerine örnekler


81

Uygulamanızın javascript'inde hangi nesne yönelimli tasarım modellerini kullanıyorsunuz ve neden?

Ekli resmi bir tasarım modeli olmasa bile kod göndermekten çekinmeyin.

Bolca javascript yazdım, ancak yaptığım şeye çok fazla nesne odaklı desen uygulamadım ve çok şey kaçırdığıma eminim.


Muhtemelen düşündüğünüz anlamda klasik OOP görmediniz. Ancak, muhtemelen prototip OOP ile özellikleri kullandınız ve bunu gerçekten fark etmediniz.
dave

Aslında (bazen) OOP kullandığımın farkındayım - OOP'yi çok daha bilinçli kullanmaya başlamak istiyorum, çünkü bu konuda çok daha bilinçli olmak istiyorum
ming yeow

Bu soruyu konu dışı olarak kapatmak için oy kullanıyorum çünkü bu sadece başkalarının kendi kodlarında yaptığı şeylerin bir listesini istiyor.
Almo

Yanıtlar:


54

Aşağıdakiler üç popüler JavaScript kalıbıdır. Kapanışlar nedeniyle bunlar kolayca uygulanabilir :

Ayrıca şunları da kontrol etmek isteyebilirsiniz:

Aşağıda, Diaz tarafından sunulan ve kitabındaki bazı konuları tartıştığı 2008 tarihli bir Google I / O konuşması:


Güzel! curry, yapmaya çalıştığım bazı genellemeleri yapmanın daha akıllıca bir yolu gibi görünüyor. zaten basit modül ve not alma biçimlerini kullanıyor - ancak şu anda nasıl yaptığımı zorlamak için bu örnekleri incelemem gerekiyor. En çok hangilerini kullanıyorsun?
ming yeow

@ming: Muhtemelen modül kalıbıdır. Uygulaması ve anlaşılması çok kolaydır ve ad aralığı ve özel değişkenler / yöntemler dahil olmak üzere bazı harika özelliklerle birlikte gelir.
Daniel Vassallo

26

Miras

Java'da klasik kalıtımı taklit etmeye oldukça yakın işler bulduğum ExtJS 3'e dayalı bir kalıtım notasyonu kullanıyorum . Temel olarak şu şekilde çalışır:

// Create an 'Animal' class by extending
// the 'Object' class with our magic method
var Animal = Object.extend(Object, {
    move : function() {alert('moving...');}
});

// Create a 'Dog' class that extends 'Animal'
var Dog = Object.extend(Animal, {
    bark : function() {alert('woof');}
});

// Instantiate Lassie
var lassie = new Dog();

// She can move and bark!
lassie.move();
lassie.bark();

İsim alanları

Eric Miraglia ile ad alanlarına bağlı kalma konusunda da hemfikirim, böylece yukarıdaki kod pencere nesnesinin dışında kendi bağlamında çalıştırılmalıdır; kodunuzun tarayıcı penceresinde çalıştırılan birçok eşzamanlı çerçeveden / kitaplıktan biri olarak çalışmasını istiyorsanız bu kritik önem taşır.

Bu, pencere nesnesine giden tek yolun kendi ad alanınız / modül nesneniz olduğu anlamına gelir:

// Create a namespace / module for your project
window.MyModule = {};

// Commence scope to prevent littering 
// the window object with unwanted variables
(function() {

    var Animal = window.MyModule.Animal = Object.extend(Object, {
         move: function() {alert('moving...');}
    });

    // .. more code

})();

Arayüzler

Ayrıca, uygulama tasarımınızı geliştirmek için arabirimler gibi daha gelişmiş OOP yapılarından da yararlanabilirsiniz. Benim bunlara yaklaşımım,Function.prototype şu satırlar boyunca bir gösterim elde etmek için onu geliştirmek :

var Dog = Object.extend(Animal, {
     bark: function() {
         alert('woof');
     }
     // more methods ..
}).implement(Mammal, Carnivore);

OO Kalıpları

Java anlamındaki 'Kalıplar'a gelince, yalnızca Tekil kalıbı (önbelleğe alma için harika) ve bir kullanıcı bir düğmeyi tıkladığında bazı eylemleri atamak gibi olay odaklı işlevsellik için Gözlemci kalıbı için kullanım buldum .

Gözlemci Modelini kullanmanın bir örneği şöyle olabilir:

// Instantiate object
var lassie = new Animal('Lassie');

// Register listener
lassie.on('eat', function(food) {
   this.food += food;
});

// Feed lassie by triggering listener
$('#feeding-button').click(function() {
    var food = prompt('How many food units should we give lassie?');
    lassie.trigger('eat', [food]);
    alert('Lassie has already eaten ' + lassie.food + ' units');
});

Ve bu, OO JS çantamdaki birkaç numara, umarım sizin için yararlıdır.

Bu yolda ilerlemek istiyorsanız Douglas Crockfords Javascript: the Good Parts'ı okumanızı tavsiye ederim . Bu şeyler için harika bir kitap.


20

Modül Modelinin hayranıyım . Genişletilebilir, bağımlı olmayan (çoğu zaman) çerçeveleri uygulamanın bir yoludur.

Misal:

Çerçeve Qşu şekilde tanımlanır:

var Q = {};

Bir işlev eklemek için:

Q.test = function(){};

Bu iki satır kod, modülleri oluşturmak için birlikte kullanılır . Modüllerin arkasındaki fikir, bu durumda hepsinin bir miktar temel çerçeveyi genişletmesi Q, ancak birbirlerine (doğru tasarlanmışsa) bağlı olmaması ve herhangi bir sırayla dahil edilebilmesidir.

Bir modülde, mevcut değilse önce çerçeve nesnesini oluşturursunuz (bu, Singleton modelinin bir örneğidir ):

if (!Q)
    var Q = {};

Q.myFunction = function(){};

Bu şekilde, ayrı dosyalarda birden çok modüle (yukarıdaki gibi) sahip olabilir ve bunları herhangi bir sırayla dahil edebilirsiniz. Bunlardan herhangi biri çerçeve nesnesini oluşturacak ve ardından genişletecektir. Çerçevenin var olup olmadığını kontrol etmeye gerek yoktur. Ardından, özel kodda bir modül / işlev olup olmadığını kontrol etmek için:

if (Q.myFunction)
    Q.myFunction();
else
    // Use a different approach/method

1
Bu son derece kullanışlı görünüyor. bunu kodunuzda nasıl kullanıyorsunuz? paylaşım için teşekkürler!
ming yeow

Bunu, ortak işlevler, UI ve diğer iki özel mekanizma için ayrı JavaScript dosyalarına sahip olduğum son bir projede kullandım. Tüm dosyalar aynı çerçeveye işlevler ekledi (yukarıda gösterdiğim yöntem kullanılarak tanımlandı) ve yukarıda yaptığım gibi işlevleri çağırdılar.
Chris Laplante

Bu tür tekniğin ana kullanımlarından biri, küresel ad alanının kirlenmesini önlemektir. Daha çok ne kirletiyor? Tek bir Qçerçeve değişkeni mi yoksa düzinelerce ve düzinelerce işlev ve değişken mi?
Chris Laplante


4

Jquery'nin yöntem zincirleme modelini gerçekten seviyorum , bir nesne üzerinde birkaç yöntem çağırmanıza izin veriyor. Tek bir kod satırında birkaç işlemi gerçekleştirmeyi gerçekten kolaylaştırır.

Misal:

$('#nav').click(function() {
   $(this).css('color','#f00').fadeOut();
});

doğru - kabul etti! Daha önce bu şekilde çalışan kendi özel yöntemlerinizi geliştirdiniz mi?
ming yeow

3

JQuery eklentilerine sahip Dekoratör modelini gerçekten seviyorum . Eklentileri ihtiyaçlarınızı karşılayacak şekilde değiştirmek yerine, yalnızca istekleri yönlendiren ve ek parametreler ve işlevler ekleyen özel bir eklenti yazın.

Örneğin, her zaman bir dizi varsayılan argümanı iletmeniz gerekiyorsa ve iş mantığına bağlı biraz farklı davranışa ihtiyacınız varsa , ihtiyaçlarınıza uyacak her şeyi yapan preve postçalışması gereken ve varsayılan argümanlarınızı ileten bir eklenti yazın. bu belirli argümanlar belirtilmemişse.

Bunun ana yararı, kitaplıklarınızı güncelleyebilmeniz ve kitaplık değişikliklerini taşıma konusunda endişelenmemenizdir. Kodunuz kırılabilir, ancak en azından kırılma şansı vardır.


Bu harika bir fikir gibi geliyor. Gerçek genişletmeyi yapmak için kod üzerinde gerçek bir örneğiniz var mı? Basit bir örnek bile herkese çok yardımcı olacaktır.
ming yeow

3

JavaScript dünyasındaki kullanışlı modellerden biri, LINQ tarafından ilk etapta popüler hale getirilen ve ayrıca jQuery'de kullanılan zincirleme modelidir.

bu örüntü, zincirleme şekilde bir sınıfın farklı yöntemlerini çağırmamızı sağlar.

bu modelin ana yapısı şu şekilde olacaktır:

var Calaculator = function (init) {
    var result = 0;
    this.add = function (x) { result += (init + x); return this; };
    this.sub = function (x) { result += (init - x); return this; };
    this.mul = function (x) { result += (init * x); return this; };
    this.div = function (x) { result += (init / x); return this; };

    this.equals = function (callback) {
        callback(result);
    }

    return this;
};


new Calaculator(0)
    .add(10)
    .mul(2)
    .sub(5)
    .div(3)
    .equals(function (result) {
        console.log(result);
    });

Bu modelin ana fikri this, Hesap Makinesi işlevinin diğer halka açık üyelerine erişimi mümkün kılan anahtar sözcüktür.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.