Pertanyaan Apa yang begitu buruk tentang lajang? [Tutup]


Itu pola tunggal adalah anggota yang dibayar penuh GoF's buku pola, tetapi belakangan ini tampaknya agak yatim oleh dunia pengembang. Saya masih menggunakan cukup banyak lajang, terutama untuk kelas pabrik, dan sementara Anda harus sedikit berhati-hati tentang masalah multithreading (seperti kelas apa pun sebenarnya), saya gagal untuk melihat mengapa mereka begitu mengerikan.

Stack Overflow terutama tampaknya menganggap bahwa semua orang setuju bahwa Singletons itu jahat. Mengapa?

Harap dukung jawaban Anda dengan "fakta, referensi, atau keahlian khusus"


1737


asal


Jawaban:


Diparafrasakan dari Brian Button:

  1. Mereka umumnya digunakan sebagai contoh global, mengapa begitu buruk? Karena Anda menyembunyikan dependensi aplikasi Anda dalam kode Anda, bukannya mengekspos mereka melalui antarmuka. Membuat sesuatu yang global untuk menghindari melewatkannya adalah a bau kode.

  2. Mereka melanggar prinsip tanggung jawab tunggal: berdasarkan fakta bahwa mereka mengendalikan ciptaan dan siklus hidup mereka sendiri.

  3. Mereka secara inheren menyebabkan kode menjadi erat digabungkan. Ini membuat berpura-pura mereka dalam ujian agak sulit dalam banyak kasus.

  4. Mereka membawa keadaan sekitar untuk seumur hidup aplikasi. Hitungan lain untuk menguji karena Anda dapat berakhir dengan situasi di mana tes perlu dipesan yang tidak besar untuk tes unit. Mengapa? Karena setiap tes unit harus independen dari yang lain.


1148



Singletons memecahkan satu (dan hanya satu) masalah.

Sumber Daya Contention.

Jika Anda memiliki beberapa sumber daya itu

(1) hanya dapat memiliki satu instance, dan

(2) Anda perlu mengelola satu kejadian itu,

Anda membutuhkan sebuah tunggal.

Tidak banyak contoh. File log adalah file besar. Anda tidak ingin hanya meninggalkan satu file log. Anda ingin menyiram, menyinkronkan dan menutupnya dengan benar. Ini adalah contoh dari satu sumber daya bersama yang harus dikelola.

Sangat jarang Anda membutuhkan seorang putra. Alasan mereka buruk adalah mereka merasa seperti itu global dan mereka adalah anggota GOF yang dibayar penuh Pola desain Book.

Ketika Anda berpikir Anda perlu global, Anda mungkin membuat kesalahan desain yang mengerikan.


399



Beberapa pengkodean sok melihat mereka sebagai global yang dimuliakan. Dengan cara yang sama seperti banyak orang membenci pergi ke pernyataan ada orang lain yang membenci ide yang pernah menggunakan global. Saya telah melihat beberapa pengembang pergi ke luar biasa untuk menghindari global karena mereka mempertimbangkan menggunakan satu sebagai pengakuan kegagalan. Aneh tapi Nyata.

Dalam prakteknya Singleton Pola hanyalah teknik pemrograman yang merupakan bagian yang berguna dari toolkit konsep Anda. Dari waktu ke waktu Anda mungkin menemukan itu adalah solusi ideal dan menggunakannya. Tetapi menggunakannya hanya agar Anda bisa membanggakan tentang menggunakan pola desain sama bodohnya dengan menolak untuk menggunakannya karena itu hanya a global.


306



Misko Hevery, dari Google, memiliki beberapa artikel menarik tentang topik ini ...

Lajang adalah Pendusta Patologis memiliki contoh pengujian unit yang mengilustrasikan bagaimana lajang dapat menyulitkan untuk mencari rantai ketergantungan dan memulai atau menguji aplikasi. Ini adalah contoh pelecehan yang cukup ekstrim, tetapi poin yang dia buat masih berlaku:

Singletons tidak lebih dari negara global. Keadaan global membuatnya begitu objek Anda dapat secara diam-diam menangkap hal-hal yang tidak dideklarasikan di API mereka, dan sebagai hasilnya, Singletons membuat API Anda menjadi pembohong patologis.

Di mana semua Singletons Gone membuat titik bahwa ketergantungan injeksi telah memudahkan untuk mendapatkan contoh untuk konstruktor yang membutuhkannya, yang meringankan kebutuhan yang mendasari dibalik Singlesons global yang buruk yang dicela dalam artikel pertama.


200



Saya pikir kebingungan ini disebabkan oleh fakta bahwa orang-orang tidak tahu aplikasi sebenarnya dari pola Singleton. Saya tidak bisa cukup menekankan ini. Singleton adalah tidak sebuah pola untuk membungkus global. Pola Singleton seharusnya hanya digunakan untuk menjamin itu satu dan hanya satu contoh dari kelas yang diberikan ada selama waktu proses.

Orang-orang berpikir Singleton adalah jahat karena mereka menggunakannya untuk global. Karena kebingungan inilah Singleton dipandang rendah. Tolong, jangan membingungkan Singletons dan global. Jika digunakan untuk tujuan itu dimaksudkan, Anda akan mendapatkan manfaat ekstrim dari pola Singleton.


103



Satu hal buruk tentang lajang adalah bahwa Anda tidak dapat memperpanjangnya dengan sangat mudah. Anda pada dasarnya harus membangun semacam itu pola dekorator atau semacam itu jika Anda ingin mengubah perilaku mereka. Juga, jika suatu hari Anda ingin memiliki beberapa cara untuk melakukan satu hal itu, itu bisa agak menyakitkan untuk diubah, tergantung pada bagaimana Anda menyusun kode Anda.

Satu hal yang perlu diperhatikan, jika Anda DO menggunakan lajang, cobalah untuk meneruskannya kepada siapa pun yang membutuhkannya daripada meminta mereka mengaksesnya secara langsung ... Kalau tidak, jika Anda pernah memilih untuk memiliki beberapa cara melakukan hal yang tunggal lakukan, itu akan menjadi agak sulit untuk berubah karena setiap kelas menanamkan ketergantungan jika mengakses langsung tunggal.

Jadi pada dasarnya:

public MyConstructor(Singleton singleton) {
    this.singleton = singleton;
}

daripada:

public MyConstructor() {
    this.singleton = Singleton.getInstance();
}

Saya yakin pola semacam ini disebut injeksi ketergantungan dan umumnya dianggap sebagai hal yang baik.

Seperti pola apa pun ... Pikirkan dan pertimbangkan apakah penggunaannya dalam situasi tertentu tidak pantas atau tidak ... Aturan dibuat untuk dilanggar biasanya, dan pola tidak boleh diterapkan mau tak mau tanpa berpikir.


71



Pola tunggal bukanlah masalah tersendiri. Masalahnya adalah bahwa pola ini sering digunakan oleh orang yang mengembangkan perangkat lunak dengan alat berorientasi objek tanpa memiliki pemahaman yang kuat tentang konsep OO. Ketika lajang diperkenalkan dalam konteks ini mereka cenderung tumbuh menjadi kelas yang tidak terkendali yang mengandung metode pembantu untuk setiap penggunaan kecil.

Lajang juga masalah dari perspektif pengujian. Mereka cenderung membuat tes unit yang terisolasi sulit untuk ditulis. Inversi kontrol (IoC) dan injeksi ketergantungan adalah pola yang dimaksudkan untuk mengatasi masalah ini dengan cara berorientasi objek yang cocok untuk pengujian unit.

Di sebuah sampah dikumpulkan lingkungan lajang dapat dengan cepat menjadi masalah berkaitan dengan manajemen memori.

Ada juga skenario multi-berulir di mana lajang bisa menjadi hambatan serta masalah sinkronisasi.


65



Seorang tunggal akan diimplementasikan menggunakan metode statis. Metode statis dihindari oleh orang-orang yang melakukan pengujian unit karena mereka tidak dapat diejek atau di-stub. Kebanyakan orang di situs ini adalah pendukung besar pengujian unit. Konvensi yang umumnya diterima untuk menghindarinya adalah menggunakan inversi kontrol pola.


52



Singletons juga buruk dalam hal ini kekelompokan. Karena itu, Anda tidak memiliki "tepat satu tunggal" di aplikasi Anda lagi.

Pertimbangkan situasi berikut: Sebagai pengembang, Anda harus membuat aplikasi web yang mengakses database. Untuk memastikan bahwa panggilan basis data serentak tidak saling berkonflik, Anda membuat penyelaan-untaian SingletonDao:

public class SingletonDao {
    // songleton's static variable and getInstance() method etc. omitted
    public void writeXYZ(...){
        synchronized(...){
            // some database writing operations...
        }
    }
}

Jadi, Anda yakin bahwa hanya satu tunggal dalam aplikasi Anda ada dan semua database melalui satu ini dan hanya SingletonDao. Lingkungan produksi Anda sekarang terlihat seperti ini: Single Singleton

Semuanya baik-baik saja sejauh ini.

Sekarang, pertimbangkan Anda ingin menyiapkan beberapa contoh aplikasi web Anda dalam sebuah klaster. Sekarang, Anda tiba-tiba memiliki sesuatu seperti ini:

Many singletons

Kedengarannya aneh, tapi sekarang Anda memiliki banyak lajang dalam aplikasi Anda. Dan itulah tepatnya yang tidak dimiliki oleh seorang lelaki: Memiliki banyak objek. Ini sangat buruk jika Anda, seperti yang ditunjukkan dalam contoh ini, ingin melakukan panggilan tersinkronisasi ke database.

Tentu saja ini adalah contoh penggunaan buruk seorang lajang. Tetapi pesan dari contoh ini adalah: Anda tidak dapat mengandalkan bahwa persis ada satu contoh tunggal dalam aplikasi Anda - terutama ketika datang ke pengelompokan.


42



  1. Ini mudah (ab) digunakan sebagai variabel global.
  2. Kelas yang bergantung pada lajang relatif lebih sulit untuk tes unit dalam isolasi.

34