it-swarm-id.com

Singleton: Bagaimana seharusnya digunakan

Sunting: Dari pertanyaan lain saya memberikan jawaban yang memiliki tautan ke banyak pertanyaan/jawaban tentang lajang: Info lebih lanjut tentang lajang di sini:

Jadi saya telah membaca utasnya Singletons: desain bagus atau tongkat penyangga?
Dan argumennya masih mengamuk.

Saya melihat Singletons sebagai Pola Desain (baik dan buruk).

Masalah dengan Singleton bukanlah Pola melainkan pengguna (maaf semua orang). Semua orang dan ayah mereka berpikir mereka bisa menerapkannya dengan benar (dan dari banyak wawancara yang saya lakukan, kebanyakan orang tidak bisa). Juga karena semua orang berpikir mereka dapat menerapkan Singleton yang benar, mereka menyalahgunakan Pola dan menggunakannya dalam situasi yang tidak tepat (mengganti variabel global dengan Singletons!).

Jadi pertanyaan utama yang perlu dijawab adalah:

  • Kapan sebaiknya Anda menggunakan Singleton
  • Bagaimana Anda menerapkan Singleton dengan benar

Harapan saya untuk artikel ini adalah bahwa kita dapat mengumpulkan bersama di satu tempat (daripada harus mencari google dan mencari beberapa situs) sumber otoritatif kapan (dan kemudian bagaimana) menggunakan Singleton dengan benar. Yang juga sesuai adalah daftar Anti-Penggunaan dan implementasi umum yang buruk yang menjelaskan mengapa mereka gagal bekerja dan untuk implementasi yang baik, kelemahan mereka.


Jadi siapkan bola:
Saya akan mengangkat tangan dan mengatakan ini adalah apa yang saya gunakan tetapi mungkin memiliki masalah.
Saya suka "Scott Myers" menangani subjek dalam buku-bukunya "Effective C++"

Situasi Baik untuk menggunakan Lajang (tidak banyak):

  • Kerangka kerja logging
  • Kolam daur ulang benang
/*
 * C++ Singleton
 * Limitation: Single Threaded Design
 * See: http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf
 *      For problems associated with locking in multi threaded applications
 *
 * Limitation:
 * If you use this Singleton (A) within a destructor of another Singleton (B)
 * This Singleton (A) must be fully constructed before the constructor of (B)
 * is called.
 */
class MySingleton
{
    private:
        // Private Constructor
        MySingleton();
        // Stop the compiler generating methods of copy the object
        MySingleton(MySingleton const& copy);            // Not Implemented
        MySingleton& operator=(MySingleton const& copy); // Not Implemented

    public:
        static MySingleton& getInstance()
        {
            // The only instance
            // Guaranteed to be lazy initialized
            // Guaranteed that it will be destroyed correctly
            static MySingleton instance;
            return instance;
        }
};

BAIK. Mari kita mendapatkan beberapa kritik dan implementasi lainnya bersama-sama.
:-)

287
Martin York

Kalian semua salah. Baca pertanyaannya. Menjawab:

Gunakan Singleton jika:

  • Anda harus memiliki satu dan hanya satu objek dari jenis dalam sistem

Jangan menggunakan Singleton jika:

  • Anda ingin menghemat memori
  • Anda ingin mencoba sesuatu yang baru
  • Anda ingin memamerkan seberapa banyak yang Anda tahu
  • Karena semua orang melakukannya (Lihat programmer kultus kargo di wikipedia)
  • Di widget antarmuka pengguna
  • Seharusnya cache
  • Dalam string
  • Dalam Sesi
  • Saya bisa sepanjang hari

Cara membuat singleton terbaik:

  • Semakin kecil, semakin baik. Saya seorang minimalis
  • Pastikan benang aman
  • Pastikan itu tidak pernah nol
  • Pastikan itu dibuat hanya sekali
  • Malas atau inisialisasi sistem? Hingga kebutuhan Anda
  • Terkadang OS atau JVM membuat lajang untuk Anda (mis. Dalam Java setiap definisi kelas adalah lajang)
  • Berikan destruktor atau entah bagaimana mencari cara membuang sumber daya
  • Gunakan sedikit memori
166
Javaxpert

Lajang memberi Anda kemampuan untuk menggabungkan dua sifat buruk dalam satu kelas. Itu salah dalam banyak hal.

Singleton memberi Anda:

  1. Akses global ke suatu objek, dan
  2. Jaminan bahwa tidak ada lebih dari satu objek jenis ini yang dapat dibuat

Nomor satu sangat mudah. Global umumnya buruk. Kita seharusnya tidak pernah membuat objek dapat diakses secara global kecuali kita benar-benar membutuhkannya.

Nomor dua mungkin terdengar masuk akal, tapi mari kita pikirkan. Kapan terakhir kali Anda ** secara tidak sengaja * membuat objek baru alih-alih merujuk yang sudah ada? Karena ini ditandai C++, mari gunakan contoh dari bahasa itu. Apakah Anda sering tidak sengaja menulis

std::ostream os;
os << "hello world\n";

Ketika Anda berniat untuk menulis

std::cout << "hello world\n";

Tentu saja tidak. Kami tidak memerlukan perlindungan terhadap kesalahan ini, karena kesalahan semacam itu tidak terjadi. Jika ya, respons yang benar adalah pulang dan tidur selama 12-20 jam dan berharap Anda merasa lebih baik.

Jika hanya satu objek yang dibutuhkan, cukup buat satu instance. Jika satu objek harus dapat diakses secara global, jadikan itu objek global. Tetapi itu tidak berarti tidak mungkin membuat contoh lain darinya.

Batasan "hanya satu contoh mungkin" tidak benar-benar melindungi kami dari kemungkinan bug. Tapi itu tidak membuat kode kita sangat sulit untuk diperbaiki dan dipelihara. Karena cukup sering kita mengetahui nanti bahwa kita memang membutuhkan lebih dari satu contoh. Kami do memiliki lebih dari satu database, kami do memiliki lebih dari satu objek konfigurasi, kami ingin beberapa penebang. Unit test kami mungkin ingin dapat membuat dan menciptakan kembali objek-objek ini setiap pengujian, untuk mengambil contoh umum.

Jadi singleton harus digunakan jika dan hanya jika, kita perlu keduanya ciri-ciri yang ditawarkannya: Jika kita membutuhkan akses global (yang jarang terjadi, karena global umumnya tidak disarankan) dan we perlu untuk cegah siapa pun dari pernah membuat lebih dari satu instance kelas (yang menurut saya seperti masalah desain). Satu-satunya alasan saya bisa melihat ini adalah jika membuat dua contoh akan merusak keadaan aplikasi kita - mungkin karena kelas berisi sejumlah anggota statis atau kekonyolan serupa. Dalam hal ini jawaban yang jelas adalah untuk memperbaiki kelas itu. Seharusnya tidak tergantung pada menjadi satu-satunya contoh.

Jika Anda membutuhkan akses global ke suatu objek, buat itu menjadi global, seperti std::cout. Tetapi jangan membatasi jumlah instance yang dapat dibuat.

Jika Anda benar-benar, secara positif perlu membatasi jumlah instance kelas menjadi hanya satu, dan tidak ada cara membuat instance kedua dapat ditangani dengan aman, maka tegakkan itu. Tetapi jangan membuatnya dapat diakses secara global juga.

Jika Anda memang membutuhkan kedua sifat tersebut, maka 1) menjadikannya singleton, dan 2) beri tahu saya untuk apa Anda membutuhkannya, karena saya kesulitan membayangkan kasus seperti itu.

71
jalf

Masalah dengan lajang bukanlah implementasinya. Mereka mengacaukan dua konsep yang berbeda, yang keduanya tidak diinginkan.

1) Lajang menyediakan mekanisme akses global ke suatu objek. Meskipun mereka mungkin sedikit lebih aman atau sedikit lebih dapat diandalkan dalam bahasa tanpa urutan inisialisasi yang didefinisikan dengan baik, penggunaan ini masih setara dengan moral variabel global. Ini adalah variabel global yang didandani dengan beberapa sintaks canggung (foo :: get_instance (), bukan g_foo, katakanlah), tetapi ia melayani tujuan yang sama persis (objek tunggal yang dapat diakses di seluruh program) dan memiliki kelemahan yang sama persis.

2) Lajang mencegah beberapa instance kelas. Jarang, IME, bahwa fitur semacam ini harus dimasukkan ke dalam kelas. Ini biasanya hal yang jauh lebih kontekstual; banyak hal yang dianggap sebagai satu-dan-hanya-satu benar-benar terjadi pada satu-satunya. IMO solusi yang lebih tepat adalah dengan hanya membuat satu instance - sampai Anda menyadari bahwa Anda membutuhkan lebih dari satu instance.

35
DrPizza

Satu hal dengan pola: jangan menyamaratakan. Mereka memiliki semua kasus saat mereka berguna, dan ketika mereka gagal.

Singleton bisa menjadi jahat ketika Anda harus test kode. Anda biasanya terjebak dengan satu instance kelas, dan dapat memilih antara membuka pintu di konstruktor atau beberapa metode untuk mengatur ulang keadaan dan sebagainya.

Masalah lainnya adalah bahwa Singleton sebenarnya tidak lebih dari variabel global yang menyamar. Ketika Anda memiliki terlalu banyak status global yang dibagi atas program Anda, banyak hal cenderung kembali, kita semua tahu itu.

Mungkin membuat pelacakan ketergantungan lebih sulit. Ketika semuanya tergantung pada Singleton Anda, lebih sulit untuk mengubahnya, dipecah menjadi dua, dll. Anda umumnya terjebak dengannya. Ini juga menghambat fleksibilitas. Selidiki beberapa Ketergantungan Injeksi kerangka kerja untuk mencoba mengatasi masalah ini.

26
Paweł Hajdan

Lajang pada dasarnya membiarkan Anda memiliki keadaan global yang kompleks dalam bahasa yang sebaliknya membuat sulit atau tidak mungkin untuk memiliki variabel global yang kompleks.

Java khususnya menggunakan lajang sebagai pengganti variabel global, karena semuanya harus terkandung dalam kelas. Yang paling dekat dengan variabel global adalah variabel statis publik, yang dapat digunakan seolah-olah mereka global dengan import static

C++ memang memiliki variabel global, tetapi urutan konstruktor variabel kelas global dipanggil tidak ditentukan. Dengan demikian, singleton memungkinkan Anda menunda pembuatan variabel global hingga pertama kali variabel itu diperlukan.

Bahasa seperti Python dan Ruby menggunakan lajang sangat sedikit karena Anda dapat menggunakan variabel global dalam suatu modul sebagai gantinya.

Jadi kapan baik/buruk menggunakan singleton? Cukup tepatnya kapan akan baik/buruk menggunakan variabel global.

12
Eli Courtwright
  • Bagaimana Anda menerapkan Singleton dengan benar

Ada satu masalah yang belum pernah saya lihat disebutkan, sesuatu yang saya temui di pekerjaan sebelumnya. Kami memiliki C++ lajang yang dibagikan di antara DLL, dan mekanisme yang biasa untuk memastikan satu instance kelas tidak bekerja. Masalahnya adalah bahwa setiap DLL mendapatkan set variabel statisnya sendiri, bersama dengan EXE. Jika fungsi get_instance Anda sebaris atau bagian dari perpustakaan statis, setiap DLL akan berakhir dengan salinan "singleton" sendiri.

Solusinya adalah memastikan kode singleton hanya didefinisikan dalam satu DLL atau EXE, atau membuat manajer singleton dengan properti tersebut untuk membagi contoh.

6
Mark Ransom

Desain C++ Modern oleh Alexandrescu memiliki singleton generik yang aman untuk diwariskan.

Untuk nilai 2p saya, saya pikir sangat penting untuk memiliki masa hidup yang ditentukan untuk lajang Anda (ketika itu benar-benar diperlukan untuk menggunakannya). Saya biasanya tidak membiarkan fungsi statis get() instantiate apa pun, dan biarkan set-up dan penghancuran ke beberapa bagian khusus aplikasi utama. Ini membantu menyoroti ketergantungan antara lajang - tetapi, seperti ditekankan di atas, yang terbaik adalah menghindarinya jika memungkinkan.

6
tenpn

Contoh pertama tidak aman utas - jika dua utas memanggil getInstance pada saat yang sama, statis itu akan menjadi PITA. Beberapa bentuk mutex akan membantu.

5
Rob

Seperti yang telah dicatat oleh orang lain, kerugian besar bagi lajang meliputi ketidakmampuan untuk memperpanjangnya, dan kehilangan kekuatan untuk membuat instantiate lebih dari satu contoh, mis. untuk tujuan pengujian.

Beberapa aspek yang berguna dari lajang:

  1. instantiasi malas atau dimuka
  2. berguna untuk objek yang membutuhkan pengaturan dan/atau negara

Namun, Anda tidak harus menggunakan singleton untuk mendapatkan manfaat ini. Anda dapat menulis objek normal yang berfungsi, lalu meminta orang mengaksesnya melalui pabrik (objek terpisah). Pabrik hanya dapat khawatir tentang instantiating satu, dan menggunakannya kembali, dll, jika perlu. Selain itu, jika Anda memprogram ke antarmuka daripada kelas yang konkret, pabrik dapat menggunakan strategi, mis. Anda dapat beralih masuk dan keluar berbagai implementasi antarmuka.

Akhirnya, sebuah pabrik cocok untuk teknologi injeksi ketergantungan seperti Spring dll.

4
lexh

Karena singleton hanya memungkinkan satu instance dibuat, ia secara efektif mengontrol replikasi instance. misalnya Anda tidak akan membutuhkan beberapa contoh pencarian - misalnya peta pencarian morse, sehingga membungkusnya dalam kelas tunggal adalah tepat. Dan hanya karena Anda memiliki satu instance dari kelas tidak berarti Anda juga terbatas pada jumlah referensi ke instance itu. Anda dapat mengantri panggilan (untuk menghindari masalah threading) ke instance dan efek perubahan yang diperlukan. Ya, bentuk umum dari singleton adalah publik global, Anda tentu dapat memodifikasi desain untuk membuat singleton terbatas akses lebih. Saya belum pernah lelah ini sebelumnya tetapi saya yakin tahu itu mungkin. Dan untuk semua orang yang berkomentar mengatakan pola tunggal sama sekali jahat Anda harus tahu ini: ya itu jahat jika Anda tidak menggunakannya dengan benar atau di dalamnya membatasi fungsionalitas yang efektif dan perilaku yang dapat diprediksi: jangan GENERALISASI.

3
gogole

Lajang berguna ketika Anda memiliki banyak kode yang dijalankan ketika Anda menginisialisasi dan objek. Misalnya, ketika Anda menggunakan iBatis ketika Anda mengatur objek kegigihan, ia harus membaca semua konfigurasi, mengurai peta, pastikan semuanya benar, dll. Sebelum membuka kode Anda.

Jika Anda melakukan ini setiap waktu, kinerja akan jauh menurun. Menggunakannya dalam singleton, Anda menerima pukulan itu sekali dan kemudian semua panggilan berikutnya tidak harus melakukannya.

3
Brian

Kebanyakan orang menggunakan lajang ketika mereka berusaha membuat diri mereka merasa senang menggunakan variabel global. Ada kegunaan yang sah, tetapi sebagian besar waktu ketika orang menggunakannya, fakta bahwa hanya ada satu contoh hanyalah fakta sepele dibandingkan dengan fakta bahwa itu dapat diakses secara global.

3
Brad Barker

Kejatuhan Singletons yang sebenarnya adalah mereka menghancurkan warisan. Anda tidak dapat menurunkan kelas baru untuk memberi Anda fungsionalitas tambahan kecuali Anda memiliki akses ke kode tempat Singleton direferensikan. Jadi, di luar kenyataan Singleton akan membuat kode Anda digabungkan dengan erat (diperbaiki dengan Pola Strategi ... alias Dependency Injection) juga akan mencegah Anda menutup bagian kode dari revisi dari (shared library).

Jadi, bahkan contoh penebang atau kumpulan utas tidak valid dan harus diganti oleh Strategi.

3
ZebZiggle

Tetapi ketika saya membutuhkan sesuatu seperti Singleton, saya sering berakhir menggunakan Schwarz Counter untuk instantiate.

2
Matt Cruikshank

Saya menggunakan Lajang sebagai tes wawancara.

Ketika saya meminta pengembang untuk memberi nama beberapa pola desain, jika yang mereka sebut adalah Singleton, mereka tidak akan dipekerjakan.

1
Matt Cruikshank

Di bawah ini adalah pendekatan yang lebih baik untuk menerapkan pola single safe thread dengan deallocating memori di destructor itu sendiri. Tetapi saya pikir destructor harus menjadi opsional karena instance singleton akan secara otomatis dihancurkan ketika program berakhir:

#include<iostream>
#include<mutex>

using namespace std;
std::mutex mtx;

class MySingleton{
private:
    static MySingleton * singletonInstance;
    MySingleton();
    ~MySingleton();
public:
    static MySingleton* GetInstance();
    MySingleton(const MySingleton&) = delete;
    const MySingleton& operator=(const MySingleton&) = delete;
    MySingleton(MySingleton&& other) noexcept = delete;
    MySingleton& operator=(MySingleton&& other) noexcept = delete;
};

MySingleton* MySingleton::singletonInstance = nullptr;
MySingleton::MySingleton(){ };
MySingleton::~MySingleton(){
    delete singletonInstance;
};

MySingleton* MySingleton::GetInstance(){
    if (singletonInstance == NULL){
        std::lock_guard<std::mutex> lock(mtx);
        if (singletonInstance == NULL)
            singletonInstance = new MySingleton();
    }
    return singletonInstance;
}

Mengenai situasi di mana kita perlu menggunakan kelas singleton dapat- Jika kita ingin mempertahankan keadaan instance selama pelaksanaan program Jika kita terlibat dalam penulisan ke dalam log eksekusi aplikasi di mana hanya satu instance dari file perlu digunakan .... dan seterusnya. Akan sangat bagus jika ada yang bisa menyarankan optimasi dalam kode saya di atas.

1
A. Gupta

Pola tunggal Meyers bekerja cukup baik sebagian besar waktu, dan pada kesempatan itu tidak selalu membayar untuk mencari sesuatu yang lebih baik. Selama konstruktor tidak akan pernah membuang dan tidak ada ketergantungan antara lajang.

Singleton adalah implementasi untuk objek yang dapat diakses secara global (GAO mulai sekarang) meskipun tidak semua GAO adalah lajang.

Penebang sendiri seharusnya bukan orang lajang, tetapi sarana untuk log idealnya dapat diakses secara global, untuk memisahkan di mana pesan log dihasilkan dari tempat atau bagaimana itu dicatat.

Evaluasi malas-malas/malas adalah konsep yang berbeda dan biasanya singleton menerapkannya juga. Itu datang dengan banyak masalah sendiri, khususnya keamanan benang dan masalah jika gagal dengan pengecualian sehingga apa yang tampak seperti ide yang baik pada saat itu ternyata tidak terlalu bagus. (Agak seperti implementasi SAP dalam string).

Dengan mengingat hal itu, GOA dapat diinisialisasi seperti ini:

namespace {

T1 * pt1 = NULL;
T2 * pt2 = NULL;
T3 * pt3 = NULL;
T4 * pt4 = NULL;

}

int main( int argc, char* argv[])
{
   T1 t1(args1);
   T2 t2(args2);
   T3 t3(args3);
   T4 t4(args4);

   pt1 = &t1;
   pt2 = &t2;
   pt3 = &t3;
   pt4 = &t4;

   dostuff();

}

T1& getT1()
{
   return *pt1;
}

T2& getT2()
{
   return *pt2;
}

T3& getT3()
{
  return *pt3;
}

T4& getT4()
{
  return *pt4;
}

Itu tidak perlu dilakukan dengan kasar seperti itu, dan jelas di perpustakaan dimuat yang berisi objek Anda mungkin ingin beberapa mekanisme lain untuk mengatur masa hidup mereka. (Tempatkan mereka di objek yang Anda dapatkan saat memuat perpustakaan).

Adapun ketika saya menggunakan lajang? Saya menggunakan mereka untuk 2 hal - Tabel tunggal yang menunjukkan perpustakaan apa yang telah dimuat dengan dlopen - Penangan pesan yang dapat dilanggan oleh para penebang dan Anda dapat mengirim pesan. Diperlukan khusus untuk penangan sinyal.

0
CashCow

Jika Anda adalah orang yang menciptakan singleton dan yang menggunakannya, jangan menjadikannya sebagai singleton (itu tidak masuk akal karena Anda dapat mengontrol singularitas objek tanpa membuatnya singleton) tetapi masuk akal ketika Anda seorang pengembang sebuah perpustakaan dan Anda ingin menyediakan hanya satu objek untuk pengguna Anda (dalam hal ini Anda yang menciptakan singleton, tetapi Anda bukan pengguna).

Lajang adalah objek jadi gunakanlah itu sebagai objek, banyak orang mengakses lajang secara langsung melalui memanggil metode yang mengembalikannya, tetapi ini berbahaya karena Anda membuat kode Anda tahu bahwa objek itu singleton, saya lebih suka menggunakan lajang sebagai objek, saya meneruskannya melalui konstruktor dan saya menggunakannya sebagai objek biasa, dengan cara itu, kode Anda tidak tahu apakah objek ini adalah lajang atau tidak dan itu membuat dependensi lebih jelas dan ini membantu sedikit untuk refactoring ...

0
La VloZ Merrill

Anti-Penggunaan:

Salah satu masalah utama dengan penggunaan tunggal berlebihan adalah bahwa pola mencegah ekstensi mudah dan bertukar implementasi alternatif. Nama kelas adalah kode keras di mana pun singleton digunakan.

0
Adam Franco

Saya menemukan mereka berguna ketika saya memiliki kelas yang merangkum banyak memori. Sebagai contoh dalam permainan baru-baru ini saya telah bekerja pada saya memiliki kelas peta pengaruh yang berisi koleksi array yang sangat besar dari memori yang berdekatan. Saya ingin semua dialokasikan saat startup, semua dibebaskan saat shutdown dan saya pasti hanya ingin satu salinannya. Saya juga harus mengaksesnya dari banyak tempat. Saya menemukan pola singleton sangat berguna dalam kasus ini.

Saya yakin ada solusi lain tetapi saya menemukan ini sangat berguna dan mudah diimplementasikan.

0

Saya pikir ini adalah versi paling kuat untuk C #:

using System;
using System.Collections;
using System.Threading;

namespace DoFactory.GangOfFour.Singleton.RealWorld
{

  // MainApp test application

  class MainApp
  {
    static void Main()
    {
      LoadBalancer b1 = LoadBalancer.GetLoadBalancer();
      LoadBalancer b2 = LoadBalancer.GetLoadBalancer();
      LoadBalancer b3 = LoadBalancer.GetLoadBalancer();
      LoadBalancer b4 = LoadBalancer.GetLoadBalancer();

      // Same instance?
      if (b1 == b2 && b2 == b3 && b3 == b4)
      {
        Console.WriteLine("Same instance\n");
      }

      // All are the same instance -- use b1 arbitrarily
      // Load balance 15 server requests
      for (int i = 0; i < 15; i++)
      {
        Console.WriteLine(b1.Server);
      }

      // Wait for user
      Console.Read();    
    }
  }

  // "Singleton"

  class LoadBalancer
  {
    private static LoadBalancer instance;
    private ArrayList servers = new ArrayList();

    private Random random = new Random();

    // Lock synchronization object
    private static object syncLock = new object();

    // Constructor (protected)
    protected LoadBalancer()
    {
      // List of available servers
      servers.Add("ServerI");
      servers.Add("ServerII");
      servers.Add("ServerIII");
      servers.Add("ServerIV");
      servers.Add("ServerV");
    }

    public static LoadBalancer GetLoadBalancer()
    {
      // Support multithreaded applications through
      // 'Double checked locking' pattern which (once
      // the instance exists) avoids locking each
      // time the method is invoked
      if (instance == null)
      {
        lock (syncLock)
        {
          if (instance == null)
          {
            instance = new LoadBalancer();
          }
        }
      }

      return instance;
    }

    // Simple, but effective random load balancer

    public string Server
    {
      get
      {
        int r = random.Next(servers.Count);
        return servers[r].ToString();
      }
    }
  }
}

Inilah versi .NET-dioptimalkan :

using System;
using System.Collections;

namespace DoFactory.GangOfFour.Singleton.NETOptimized
{

  // MainApp test application

  class MainApp
  {

    static void Main()
    {
      LoadBalancer b1 = LoadBalancer.GetLoadBalancer();
      LoadBalancer b2 = LoadBalancer.GetLoadBalancer();
      LoadBalancer b3 = LoadBalancer.GetLoadBalancer();
      LoadBalancer b4 = LoadBalancer.GetLoadBalancer();

      // Confirm these are the same instance
      if (b1 == b2 && b2 == b3 && b3 == b4)
      {
        Console.WriteLine("Same instance\n");
      }

      // All are the same instance -- use b1 arbitrarily
      // Load balance 15 requests for a server
      for (int i = 0; i < 15; i++)
      {
        Console.WriteLine(b1.Server);
      }

      // Wait for user
      Console.Read();    
    }
  }

  // Singleton

  sealed class LoadBalancer
  {
    // Static members are lazily initialized.
    // .NET guarantees thread safety for static initialization
    private static readonly LoadBalancer instance =
      new LoadBalancer();

    private ArrayList servers = new ArrayList();
    private Random random = new Random();

    // Note: constructor is private.
    private LoadBalancer()
    {
      // List of available servers
      servers.Add("ServerI");
      servers.Add("ServerII");
      servers.Add("ServerIII");
      servers.Add("ServerIV");
      servers.Add("ServerV");
    }

    public static LoadBalancer GetLoadBalancer()
    {
      return instance;
    }

    // Simple, but effective load balancer
    public string Server
    {
      get
      {
        int r = random.Next(servers.Count);
        return servers[r].ToString();
      }
    }
  }
}

Anda dapat menemukan pola ini di dotfactory.com .

0
artur02

Saya masih belum mengerti mengapa seorang lajang harus mendunia.

Saya akan menghasilkan singleton di mana saya menyembunyikan basis data di dalam kelas sebagai variabel statis konstan pribadi dan membuat fungsi kelas yang memanfaatkan basis data tanpa pernah memaparkan basis data kepada pengguna.

Saya tidak melihat mengapa fungsi ini buruk.

0
Zachary Kraus