Apa cara paling sederhana / paling bersih untuk menerapkan pola singleton dalam JavaScript?
javascript
function
design-patterns
singleton
Jakub Arnold
sumber
sumber
Jawaban:
Saya pikir cara termudah adalah dengan mendeklarasikan objek literal sederhana:
Jika Anda ingin anggota pribadi menggunakan instance tunggal Anda, Anda dapat melakukan sesuatu seperti ini:
Ini telah disebut dengan pola modul , pada dasarnya memungkinkan Anda untuk merangkum anggota pribadi pada objek, dengan mengambil keuntungan dari penggunaan penutupan .
UPDATE: Saya ingin menambahkan bahwa jika Anda ingin mencegah modifikasi objek singleton, Anda dapat membekukannya , menggunakan
Object.freeze
metode ES5 .Itu akan membuat objek tidak berubah, mencegah modifikasi pada struktur dan nilainya.
Selain itu saya ingin menyebutkan bahwa jika Anda menggunakan ES6, Anda dapat mewakili singleton menggunakan Modul ES dengan sangat mudah, dan Anda bahkan dapat memegang status privat dengan mendeklarasikan variabel pada cakupan modul :
Kemudian Anda bisa mengimpor objek singleton untuk menggunakannya:
sumber
publicMethod1
meneleponpublicMethod2
?getInstance
metode statis , dan konstruktor pribadi-, tapi IMO, ini adalah cara paling "sederhana" untuk membangun objek singleton dalam Javascript, dan pada akhirnya memenuhi tujuan yang sama-objek tunggal, yang Anda tidak dapat menginisialisasi lagi (tidak ada konstruktor, itu hanya sebuah objek) -. Tentang kode yang Anda tautkan, ada beberapa masalah, tukara
danb
deklarasi variabel dan pengujiana === window
. Bersulang.Saya pikir pendekatan terbersih adalah sesuatu seperti:
Setelah itu, Anda dapat memanggil fungsi sebagai
sumber
delete instance.constructor
:x = SingletonClass.getInstance();delete x.constructor;new x.constructor;
Saya tidak yakin saya setuju dengan pola modul yang digunakan sebagai pengganti pola tunggal. Saya sering melihat lajang digunakan dan dilecehkan di tempat-tempat di mana mereka sama sekali tidak perlu, dan saya yakin pola modul mengisi banyak celah di mana programmer akan menggunakan singleton, namun pola modul bukan singleton.
pola modul:
Segala sesuatu yang diinisialisasi dalam pola modul terjadi ketika
Foo
dideklarasikan. Selain itu, pola modul dapat digunakan untuk menginisialisasi konstruktor, yang kemudian dapat dipakai beberapa kali. Sementara pola modul adalah alat yang tepat untuk banyak pekerjaan, itu tidak setara dengan singleton.pola singleton:
bentuk pendek bentuk panjang, menggunakan pola modulDi kedua versi pola Singleton yang saya berikan, konstruktor itu sendiri dapat digunakan sebagai accessor:
Jika Anda merasa tidak nyaman menggunakan konstruktor seperti ini, Anda bisa melempar kesalahan dalam
if (instance)
pernyataan, dan tetap menggunakan form panjang:Saya juga harus menyebutkan bahwa pola singleton cocok dengan pola fungsi konstruktor implisit:
sumber
var singleton = {}
tidak sesuai dengan definisi itu.var singleton = {}
adalah bagaimana Anda menerapkan singleton dalam Javascript .Dalam
es6
:sumber
instance
bidang. Seperti saat ini (instance
diatur kethis
) kelas ini mungkin memiliki bidang lain juga dan pembekuan tidak masuk akal.Berikut ini berfungsi di simpul v6
Kami menguji:
sumber
Dalam ES6 cara yang tepat untuk melakukan ini adalah:
Atau, jika Anda tidak ingin kesalahan dilemparkan pada pembuatan instance kedua, Anda bisa mengembalikan instance terakhir, seperti:
sumber
instance
dan_instance
. Itu hanya konvensi penamaan dalam bahasa pemrograman yang kami beri nama variabel pribadi yang diawali dengan garis bawah. Saya menduga alasan kode Anda untuk tidak berfungsi adalah karena Anda menggunakanthis.instance
alih-alihMyClass.instance
Ada lebih dari satu cara untuk menguliti kucing :) Tergantung pada selera atau kebutuhan spesifik Anda, Anda dapat menerapkan salah satu solusi yang diusulkan. Saya pribadi mencari solusi pertama CMS bila memungkinkan (ketika Anda tidak membutuhkan privasi). Karena pertanyaannya adalah yang paling sederhana dan paling bersih, itulah pemenangnya. Atau bahkan:
Ini (kutipan dari blog saya) ...
tidak masuk akal (contoh blog saya juga tidak) karena tidak memerlukan vars pribadi, jadi hampir sama dengan:
sumber
this.f(){}
Saya mencela jawaban saya, melihat jawaban saya yang lain .
Biasanya pola modul (lihat jawaban CMS) yang BUKAN pola tunggal cukup baik. Namun salah satu fitur singleton adalah inisialisasi tertunda hingga objek diperlukan. Pola modul tidak memiliki fitur ini.
Proposisi saya (CoffeeScript):
Yang dikompilasi dalam JavaScript ini:
Maka saya bisa melakukan hal berikut:
sumber
Jawaban singkat:
Karena sifat non-pemblokiran JavaScript, Singletons dalam JavaScript benar-benar jelek digunakan. Variabel global akan memberi Anda satu contoh melalui seluruh aplikasi juga tanpa semua panggilan balik ini, pola modul dengan lembut menyembunyikan internal di belakang antarmuka. Lihat jawaban @CMS.
Tapi, karena Anda menginginkan seorang singleton ...
Pemakaian:
Penjelasan:
Lajang memberi Anda lebih dari satu contoh melalui seluruh aplikasi: inisialisasi mereka tertunda hingga penggunaan pertama. Ini adalah hal yang sangat besar ketika Anda berurusan dengan objek yang inisialisasi mahal. Mahal biasanya berarti I / O dan dalam JavaScript I / O selalu berarti panggilan balik.
Jangan percayai jawaban yang memberi Anda antarmuka
instance = singleton.getInstance()
, mereka semua kehilangan intinya.Jika mereka tidak menerima panggilan balik untuk dijalankan ketika instance sudah siap, maka mereka tidak akan berfungsi ketika initializer melakukan I / O.
Ya, panggilan balik selalu terlihat lebih buruk daripada panggilan fungsi yang segera mengembalikan contoh objek. Tetapi sekali lagi: ketika Anda melakukan I / O, callback wajib. Jika Anda tidak ingin melakukan I / O, maka instantiation cukup murah untuk melakukannya pada awal program.
Contoh 1, penginisialisasi murah:
Contoh 2, inisialisasi dengan I / O:
Dalam contoh ini
setTimeout
memalsukan beberapa operasi I / O yang mahal. Ini menggambarkan mengapa lajang di JavaScript benar-benar membutuhkan panggilan balik.sumber
Saya mendapatkan contoh ini dari Pola JavaScript Membangun Aplikasi yang Lebih Baik dengan Pola Pengodean dan Desain Oleh Stoyan Stefanov buku jika Anda memerlukan beberapa kelas implementasi sederhana seperti objek singltone Anda dapat menggunakan fungsi langsung sebagai berikut:
Dan Anda dapat memeriksa contoh ini dengan mengikuti test case:
Pendekatan ini melewati semua kasus uji sementara implementasi statis pribadi akan gagal ketika ekstensi prototipe digunakan (bisa diperbaiki tetapi tidak akan sederhana) dan implementasi statis publik kurang disarankan karena misalnya terpapar ke publik.
Demo jsFiddly.
sumber
Saya pikir saya telah menemukan cara paling bersih untuk memprogram dalam JavaScript, tetapi Anda akan memerlukan imajinasi. Saya mendapat ide ini dari teknik kerja di buku "javascript bagian yang baik".
Alih-alih menggunakan kata kunci baru, Anda dapat membuat kelas seperti ini:
Anda dapat instantiate objek di atas dengan mengatakan:
Sekarang dengan metode kerja ini dalam pikiran Anda dapat membuat singleton seperti ini:
Sekarang Anda bisa mendapatkan contoh Anda dengan menelepon
Saya pikir ini adalah cara yang paling rapi karena "Kelas" yang lengkap bahkan tidak dapat diakses.
sumber
@CMS dan @zzzzBov sama-sama memberikan jawaban yang bagus, tetapi hanya untuk menambahkan interpretasi saya sendiri berdasarkan saya telah pindah ke pengembangan node.js yang berat dari PHP / Zend Framework di mana pola singleton adalah umum.
Kode yang didokumentasikan komentar berikut ini didasarkan pada persyaratan berikut:
Kode saya sangat mirip dengan @ zzzzBov, kecuali saya sudah menambahkan rantai prototipe ke konstruktor dan lebih banyak komentar yang akan membantu mereka yang berasal dari PHP atau bahasa serupa menerjemahkan OOP tradisional ke sifat prototipe Javascripts. Mungkin bukan yang "paling sederhana" tapi saya percaya itu yang paling tepat.
Perhatikan bahwa secara teknis, fungsi anonim yang dijalankan sendiri itu sendiri adalah Singleton sebagaimana ditunjukkan dengan baik dalam kode yang disediakan oleh @CMS. Satu-satunya tangkapan di sini adalah bahwa tidak mungkin untuk mengubah rantai prototipe konstruktor ketika konstruktor itu sendiri anonim.
Perlu diingat bahwa untuk Javascript, konsep "publik" dan "pribadi" tidak berlaku seperti di PHP atau Java. Tapi kami telah mencapai efek yang sama dengan memanfaatkan aturan Javascript tentang ketersediaan ruang lingkup fungsional.
sumber
var a = Singleton.getInstance('foo'); var b = new a.constructor('bar');
Tidak yakin mengapa tidak ada yang mengemukakan ini, tetapi Anda bisa melakukannya:
sumber
Jawaban paling jelas harus yang ini dari buku Belajar Pola Desain JavaScript oleh Addy Osmani.
sumber
Saya percaya ini adalah cara paling sederhana / paling bersih dan paling intuitif meskipun membutuhkan ES7:
Kode sumbernya dari: adam-bien.com
sumber
new Singleton()
Ada apa dengan ini?
sumber
Test = Klass; t1 = new Test(); t2 = new Test();
- tidak ada kesempatan untuk mengubah nama kelas atau memilih namespace yang berbeda.dapatkah saya menaruh 5 koin saya. Saya memiliki fungsi konstruktor, mis.
Yang perlu saya lakukan hanyalah setiap objek yang dibuat oleh CF ini akan sama.
uji
sumber
Saya telah menemukan yang berikut ini sebagai pola Singleton termudah, karena menggunakan operator baru membuat ini segera tersedia dalam fungsi, menghilangkan kebutuhan untuk mengembalikan objek literal:
sumber
Berikut adalah contoh sederhana untuk menjelaskan pola tunggal dalam javascript.
sumber
Saya membutuhkan beberapa lajang dengan:
dan inilah yang saya pikirkan:
args harus Array agar ini berfungsi sehingga jika Anda memiliki variabel kosong, cukup masukkan []
Saya menggunakan objek jendela dalam fungsi tetapi saya bisa melewati parameter untuk membuat ruang lingkup saya sendiri
parameter nama dan konstruk hanya String agar window [] berfungsi tetapi dengan beberapa pengecekan tipe sederhana, window.name dan window.construct juga dimungkinkan.
sumber
Bagaimana dengan cara ini, hanya memastikan kelas tidak bisa baru lagi.
Dengan ini, Anda dapat menggunakan
instanceof
op, juga, Anda dapat menggunakan rantai prototipe untuk mewarisi kelas, ini adalah kelas reguler, tetapi tidak bisa baru itu, jika Anda ingin mendapatkan contoh cukup gunakangetInstance
Jika Anda tidak ingin mengekspos
instance
anggota tersebut, tutup saja.sumber
Berikut ini adalah cuplikan dari jalan saya untuk menerapkan pola tunggal. Ini terjadi pada saya selama proses wawancara dan saya merasa bahwa saya harus menangkap ini di suatu tempat.
hal yang sama dapat ditemukan di halaman intisari saya
sumber
sumber
Bukankah ini juga singleton?
sumber
Anda dapat melakukannya dengan dekorator seperti dalam contoh di bawah ini untuk TypeScript:
Maka Anda menggunakan singleton Anda seperti ini:
Pada tulisan ini, dekorator tidak tersedia di mesin JavaScript. Anda perlu memastikan runtime JavaScript Anda memiliki dekorator yang benar-benar diaktifkan atau menggunakan kompiler seperti Babel dan TypeScript.
Juga perhatikan bahwa instance singleton dibuat "malas", yaitu, dibuat hanya ketika Anda menggunakannya untuk pertama kali.
sumber
Pola modul: dalam "gaya yang lebih mudah dibaca". Anda dapat dengan mudah melihat metode mana yang publik dan mana yang privat
sekarang Anda dapat menggunakan metode publik seperti
module.method2 (); // -> Saya memanggil metode pribadi melalui peringatan metode publik ("Hai, metode pribadi")
http://jsfiddle.net/ncubica/xMwS9/
sumber
Singleton:
Pastikan kelas hanya memiliki satu instance dan memberikan titik akses global untuk itu.
Pola Singleton membatasi jumlah instance objek tertentu menjadi hanya satu. Contoh tunggal ini disebut singleton.
Objek Singleton diimplementasikan sebagai fungsi anonim langsung. Fungsi dijalankan segera dengan membungkusnya dalam tanda kurung diikuti oleh dua tanda kurung tambahan. Itu disebut anonim karena tidak memiliki nama.
Program Sampel,
sumber
Simplest / Cleanest bagi saya berarti juga hanya untuk memahami dan tidak ada lonceng & peluit seperti yang banyak dibahas dalam diskusi versi Java:
Apa cara yang efisien untuk menerapkan pola tunggal di Jawa?
Jawaban yang paling cocok / paling bersih di sana dari sudut pandang saya adalah:
https://stackoverflow.com/a/70824/1497139
Dan itu hanya sebagian dapat diterjemahkan ke JavaScript. Beberapa perbedaan dalam Javascript adalah:
Tetapi mengingat sintaks ECMA terbaru adalah mungkin untuk mendekati:
Pola singleton sebagai contoh kelas JavaScript
Contoh Penggunaan
Contoh Hasil
sumber
Jika Anda masuk kelas:
Uji:
sumber
Jika Anda ingin menggunakan kelas:
Output untuk yang di atas adalah:
Cara lain menulis Singleton menggunakan fungsi
Output untuk yang di atas adalah:
sumber