CodeGym/Blog Java/rawak/Kelas Singleton Java
John Squirrels
Tahap
San Francisco

Kelas Singleton Java

Diterbitkan dalam kumpulan
Hai! Hari ini kita akan menyelami butiran pelbagai corak reka bentuk, bermula dengan corak Java Singleton. Mari kita semak: apa yang kita tahu tentang corak reka bentuk secara umum? Corak reka bentuk ialah amalan terbaik yang boleh kita gunakan untuk menyelesaikan beberapa masalah yang diketahui. Corak reka bentuk biasanya tidak terikat dengan mana-mana bahasa pengaturcaraan. Fikirkannya sebagai satu set pengesyoran untuk membantu anda mengelakkan kesilapan dan mengelakkan mencipta semula roda.Corak reka bentuk: Singleton - 1

Apakah singleton di Jawa?

Singleton ialah salah satu corak reka bentuk peringkat kelas yang paling mudah. Kadangkala orang berkata "kelas ini ialah singleton", yang bermaksud bahawa kelas itu melaksanakan corak reka bentuk tunggal. Kadangkala perlu menulis kelas di mana kita mengehadkan instantiasi kepada objek tunggal. Contohnya, kelas yang bertanggungjawab untuk mengelog atau menyambung ke pangkalan data. Corak reka bentuk singleton menerangkan cara kita boleh mencapai ini. Singleton ialah corak reka bentuk yang melakukan dua perkara:
  1. Ia menjamin bahawa hanya akan ada satu contoh kelas.

  2. Ia menyediakan satu titik akses global kepada contoh itu.

Oleh itu, terdapat dua ciri yang menjadi ciri hampir setiap pelaksanaan corak tunggal:
  1. Pembina persendirian. Ini mengehadkan keupayaan untuk mencipta objek kelas di luar kelas itu sendiri.

  2. Kaedah statik awam yang mengembalikan contoh kelas. Kaedah ini dipanggil getInstance . Ini ialah titik akses global kepada contoh kelas.

Pilihan pelaksanaan

Corak reka bentuk tunggal digunakan dalam pelbagai cara. Setiap pilihan adalah baik dan buruk dengan caranya sendiri. Seperti biasa, tiada pilihan yang sempurna di sini, tetapi kita harus berusaha untuk mendapatkannya. Pertama sekali, mari kita tentukan apa yang membentuk baik dan buruk, dan apakah metrik yang mempengaruhi cara kita menilai pelbagai pelaksanaan corak reka bentuk. Mari kita mulakan dengan kebaikan. Berikut ialah faktor yang menjadikan pelaksanaan lebih juicy dan menarik:
  • Inisialisasi malas: contoh tidak dibuat sehingga diperlukan.

  • Kod mudah dan telus: metrik ini, sudah tentu, adalah subjektif, tetapi ia penting.

  • Keselamatan benang: operasi yang betul dalam persekitaran berbilang benang.

  • Prestasi tinggi dalam persekitaran berbilang benang: sedikit atau tiada sekatan benang apabila berkongsi sumber.

Sekarang keburukan. Kami akan menyenaraikan faktor yang meletakkan pelaksanaan dalam cahaya yang buruk:
  • Tiada permulaan malas: apabila kelas dimuatkan apabila aplikasi bermula, tidak kira sama ada ia diperlukan atau tidak (secara paradoks, dalam dunia IT adalah lebih baik untuk menjadi malas)

  • Kod yang rumit dan sukar dibaca. Metrik ini juga subjektif. Jika mata anda mula berdarah, kami akan menganggap pelaksanaannya bukanlah yang terbaik.

  • Kekurangan keselamatan benang. Dalam erti kata lain, "bahaya benang". Operasi yang salah dalam persekitaran berbilang benang.

  • Prestasi buruk dalam persekitaran berbilang benang: benang menyekat satu sama lain sepanjang masa atau selalunya apabila berkongsi sumber.

Kod

Kini kami bersedia untuk mempertimbangkan pelbagai pilihan pelaksanaan dan menunjukkan kebaikan dan keburukan:

Mudah

public class Singleton {
    private static final Singleton INSTANCE = new Singleton();

    private Singleton() {
    }

    public static Singleton getInstance() {
        return INSTANCE;
    }
}
Pelaksanaan paling mudah. Kelebihan:
  • Kod mudah dan telus

  • Keselamatan benang

  • Prestasi tinggi dalam persekitaran berbilang benang

Keburukan:
  • Tiada permulaan yang malas.
Dalam usaha untuk memperbaiki kelemahan sebelumnya, kami mendapat pelaksanaan nombor dua:

Inisialisasi malas

public class Singleton {
  private static final Singleton INSTANCE;

  private Singleton() {}

  public static Singleton getInstance() {
    if (INSTANCE == null) {
      INSTANCE = new Singleton();
    }
    return INSTANCE;
  }
}
Kelebihan:
  • Inisialisasi malas.

Keburukan:
  • Tidak selamat benang

Pelaksanaan ini menarik. Kami boleh memulakan dengan malas, tetapi kami telah kehilangan keselamatan benang. Jangan risau — kami menyegerakkan segala-galanya dalam pelaksanaan nombor tiga.

Akses disegerakkan

public class Singleton {
  private static final Singleton INSTANCE;

  private Singleton() {
  }

  public static synchronized Singleton getInstance() {
    if (INSTANCE == null) {
      INSTANCE = new Singleton();
    }
    return INSTANCE;
  }
}
Kelebihan:
  • Inisialisasi malas.

  • Keselamatan benang

Keburukan:
  • Prestasi berbilang benang yang lemah

Cemerlang! Dalam pelaksanaan nombor tiga, kami memulihkan keselamatan benang! Sudah tentu, ia perlahan... Kini kaedah getInstance disegerakkan, jadi ia boleh dilaksanakan dengan hanya satu utas pada satu masa. Daripada menyegerakkan keseluruhan kaedah, kita sebenarnya hanya perlu menyegerakkan bahagiannya yang memulakan kejadian baharu. Tetapi kita tidak boleh hanya menggunakan blok yang disegerakkan untuk membalut bahagian yang bertanggungjawab untuk mencipta contoh baharu. Melakukannya tidak akan memastikan keselamatan benang. Semuanya lebih rumit. Penyegerakan yang betul boleh dilihat di bawah:

Penguncian yang disemak dua kali

public class Singleton {
    private static final Singleton INSTANCE;

  private Singleton() {
  }

    public static Singleton getInstance() {
        if (INSTANCE == null) {
            synchronized (Singleton.class) {
                if (INSTANCE == null) {
                    INSTANCE = new Singleton();
                }
            }
        }
        return INSTANCE;
    }
}
Kelebihan:
  • Inisialisasi malas.

  • Keselamatan benang

  • Prestasi tinggi dalam persekitaran berbilang benang

Keburukan:
  • Tidak disokong dalam versi Java yang lebih awal di bawah 1.5 (penggunaan kata kunci yang tidak menentu ditetapkan sejak versi 1.5)

Ambil perhatian bahawa untuk pilihan pelaksanaan ini berfungsi dengan betul, salah satu daripada dua syarat mesti dipenuhi. Pembolehubah INSTANCE mestilah sama ada muktamad atau tidak menentu . Pelaksanaan terakhir yang akan kita bincangkan hari ini ialah singleton pemegang kelas .

Pemegang kelas

public class Singleton {

   private Singleton() {
   }

   private static class SingletonHolder {
       public static final Singleton HOLDER_INSTANCE = new Singleton();
   }

   public static Singleton getInstance() {
       return SingletonHolder.HOLDER_INSTANCE;
   }
}
Kelebihan:
  • Inisialisasi malas.

  • Keselamatan benang.

  • Prestasi tinggi dalam persekitaran berbilang benang.

Keburukan:
  • Operasi yang betul memerlukan jaminan bahawa objek tunggal dimulakan tanpa ralat. Jika tidak, panggilan pertama kepada kaedah getInstance akan menghasilkan ExceptionInInitializerError , dan semua panggilan seterusnya akan menghasilkan NoClassDefFoundError .

Pelaksanaan ini hampir sempurna. Ia malas, dan benang selamat, dan pantas. Tetapi ia mempunyai nuansa, seperti yang dijelaskan dalam senarai kontra. Perbandingan pelbagai pelaksanaan corak tunggal:
Perlaksanaan Inisialisasi malas Keselamatan benang Prestasi berbilang benang Bila nak guna?
Mudah - + Cepat tidak pernah. Atau mungkin apabila permulaan malas tidak penting. Tetapi tidak akan menjadi lebih baik.
Inisialisasi malas + - Tidak berkaitan Sentiasa apabila multithreading tidak diperlukan
Akses disegerakkan + + Lambat tidak pernah. Atau mungkin apabila prestasi berbilang benang tidak penting. Tetapi tidak akan menjadi lebih baik.
Penguncian yang disemak dua kali + + Cepat Dalam kes yang jarang berlaku apabila anda perlu mengendalikan pengecualian semasa mencipta singleton (apabila singleton pemegang kelas tidak berkenaan)
Pemegang kelas + + Cepat Setiap kali multithreading diperlukan dan ada jaminan bahawa objek tunggal akan dicipta tanpa masalah.

Kebaikan dan keburukan corak singleton

Secara umum, singleton melakukan apa yang diharapkan daripadanya:
  1. Ia menjamin bahawa hanya akan ada satu contoh kelas.

  2. Ia menyediakan satu titik akses global kepada contoh itu.

Walau bagaimanapun, corak ini mempunyai kelemahan:
  1. Singleton melanggar prinsip tanggungjawab tunggal: sebagai tambahan kepada tugas langsungnya, kelas tunggal juga mengawal bilangan kejadian.

  2. Kebergantungan kelas biasa pada singleton tidak kelihatan dalam kontrak awam kelas.

  3. Pembolehubah global adalah buruk. Akhirnya, singleton bertukar menjadi pembolehubah global yang besar.

  4. Kehadiran singleton mengurangkan kebolehujian aplikasi secara keseluruhan dan kelas yang menggunakan singleton khususnya.

Dan itu sahaja! :) Kami telah meneroka Kelas Singleton Java bersama anda. Kini, sepanjang hayat anda, apabila berbual dengan rakan pengaturcara anda, anda boleh menyebut bukan sahaja betapa baiknya corak itu, tetapi juga beberapa perkataan tentang apa yang menjadikannya buruk. Semoga berjaya menguasai ilmu baru ini.

Bacaan tambahan:

Komen
  • Popular
  • Baru
  • Tua
Anda mesti log masuk untuk meninggalkan ulasan
Halaman ini tidak mempunyai sebarang ulasan lagi