Web sitemin kullanıcıları hakkında bilgi depolamak için bir veritabanı yapıyorum (stuts2 ve dolayısıyla Java EE teknolojisi) kullanıyorum. Veritabanı için bir DBManager yapacağım. burada kalıp veya daha ziyade tüm yöntemleri statik yapmak?
Bu DBManager'ı Kullanıcı profilleri ekleme, silme ve güncelleme gibi temel şeyler için kullanacağım. Bununla birlikte, diğer tüm sorgulama amaçları için kullanacağım, örneğin bir kullanıcı adının mevcut olup olmadığını öğrenmek ve tüm kullanıcıları yönetim amaçlı ve bunun gibi şeyler için almak için.
Sorularım
Not; Veritabanı bundan daha büyük. Burada sadece Kullanıcı Bilgilerini saklamak için kullanacağım tablolar hakkında konuşuyorum.
Neden tek seçenek ve statik yöntem tek seçenek?
Benim açımdan, her iki seçenek de oldukça kötü. Singleton AntiPattern konusunu okuyun. Singleton Paterninin çoğu kullanım durumu yanlıştır.
Sizin durumunuzda, bir örnek nesne ve bağımlılık enjeksiyonu (bir DI çerçevesi kullanıyorsanız) veya bir Servis bulucu/Kayıt defteri düzeni
Tek bir sınıfla, oluşturulan nesneyi nasıl yönettiğiniz konusunda daha fazla kontrole sahip olursunuz.
İlk olarak, bir singleton bir nesnedir. Statik yöntem, nesnenin bir örneğini döndürür ve yalnızca tek bir örnek veya isterseniz daha fazlasını oluşturmanıza olanak tanır.
Singletonlar da tembel olarak yüklenir, yani ilk çağrılıncaya kadar somutlaştırılmazlar.
Singleton statik yöntemler kullanmaz, bu nedenle statik olmayan bir bağlamda kullanmakta sorun yaşamayacaksınız.
Tektonlar genişletilebilir/alt sınıflara ayrılabilir.
Nesneler oldukları için, bağımlılık enjeksiyonu kavramlarını kullanarak bazı harika tasarım modellerinin oluşturulmasına izin veren diğer nesnelere enjekte edilebilirler. Örneğin, Spring Bean IoC (Kontrol Bağımlılığı Enjeksiyonunun İnversiyonu) modeli bu şekilde çalışır.
İkisi de idealdir, özellikle bir grup statik değildir. İşte deneyimlerime göre gerçek bir dünya örneği. Bir veritabanıyla konuştuk. Herkes "sadece bir tane olacak" dedi, bu yüzden birisi Spring tarafından yapılandırılan standart bir singleton kullandı. Sonra yeni bir gereksinim eklendi: verilerimizi başka (uzak) veritabanına kopyalayabilmek için. Hata. DB'yi temsil eden gerçek bir Nesnemiz olduğundan ve bu "nadiren kullanılan" bir özellik olduğu için, geçici bir kopya yaparak ve alanları ve değerleri değiştirerek onu hackleyebildim, ancak bu küresel statiklerle uygulanmış olsaydı, gerçek bir felaket.
Deneyimlerime göre, "onlar" sadece bir DB, bir kullanıcı, bir uygulama, bir ana pencere, vb. Olacağını söylediğinde, "onlar" yanlış. Singlton ile en azından yeniden düzenleme ve düzeltme şansı.
All-statik-yöntemler ile tekli bir kalıp uygulama arasındaki fark nedir?
Her ikisi de aynı etkiye sahiptir: yöntemi içeren sınıfın bir örneğini nasıl alacağınıza bakmadan bir sınıf yöntemini çağırabilirsiniz.
Ancak Unittesting'i uygulamak istiyorsanız statik yöntemler daha sorunludur çünkü bunlar kolaylıkla alaycı olamaz.
Test perspektifinden bakıldığında, bunları taklitlerle birim haline getirilebilir hale getirmek için tekil anahtarları kullanan kodu yeniden yazmak daha kolaydır.
En esnek ruh, Dependency_injection bir di-container-framework kullanıyor olsanız da (@ Tazzy531 tarafından önerildiği gibi) veya bağımlılıkları koda göre bağlarsanız olacaktır.
Umarım buradaki ana soruyu cevaplar.
SO'da zaten birkaç harika cevap var . Onlara sadece alıntı yapacağım.
En iyi cevap, Heinzi :
Bir single, bir uygulamaya bir tür global durum eklemek için kullanılır. Vatansızsa, tek birton kullanma noktasını da görmüyorum, aksi takdirde
- öngörülebilir gelecekte devletle genişletmeyi umuyorsunuz veya
- belirli bir teknik nedenle nesne örneğine ihtiyacınız var (örneğin, C #
SyncLockifadesi için, bu zaten oldukça getirilmiş olsa da) veya
- mirasa ihtiyacınız var, yani singletonunuzu aynı arayüzü ancak farklı bir uygulamayı kullanarak başka biriyle kolayca değiştirmek isteyebilirsiniz. Örneğin, Java) içindeki
Toolkit.getDefaultToolkit()yöntemi, tam türü sisteme bağlı olan bir singleton döndürür.
back2dos ile ilgili yüksek yorum:
(...) singletonlar küresel devletleri tanıtmak için yanlış kullanılır. Tek birtonun amacı, bir nesneyi global olarak erişilebilir kılmak değil, bir nesnenin sadece bir kez başlatıldığını zorlamaktır. Küresel nesneler gerekli bir kötülüktür. Gerçekten gerekli olmadıkça, bunları kullanmamaya çalışın, çünkü genellikle her yerde SomeSingleton.getInstance (). SomeMethod () ile yüksek bağlantıya yol açarlar.
tzaman ayrıca iyi bir cevap yazdı:
Bağımlılık Enjeksiyon statik yöntemler sınıfı yerine kullanılan durumsuz bir single için bir durum görebiliyordu.
Doğrudan kullandığınız yardımcı programlardan oluşan bir yardımcı sınıfınız varsa, gizli bir bağımlılık oluşturur; onu kimin nerede kullanabileceği konusunda hiçbir kontrole sahip değilsiniz. Aynı yardımcı sınıfı vatansız bir singleton örneği aracılığıyla enjekte etmek, nerede ve nasıl kullanıldığını kontrol etmenizi ve gerektiğinde onu/alay etmesini vb.
Tek bir örnek yapmak, türden herhangi bir nesneyi gereğinden fazla ayırmamanızı sağlar (çünkü yalnızca bir taneye ihtiyacınız vardır).
Ve son olarak Sebastien da kendini iyi cevapladı:
Aslında burada belirtilmeyen başka bir cevap buldum: statik yöntemler test etmek daha zordur.
Test çerçevelerinin çoğunun alay örneği örnekleri için harika çalıştığı görülüyor, ancak birçoğu statik yöntemlerin alayını iyi bir şekilde ele almıyor.
Olduğu söyleniyor, Toolbox desen kullanmanızı öneririz.