Aşağıdaki cevap yanlış, ancak başkalarının ondan öğrenmesini sağlayacağım (aşağıya bakın)
İçinde ExampleA, aynı Configörneği birden çok sınıfta kullanabilirsiniz. Bununla birlikte, Configtüm uygulama içinde yalnızca bir örnek olması gerekiyorsa Config, birden çok örneğine sahip olmaktan kaçınmak için Singleton desenini uygulamayı düşünün Config. Ve eğer ConfigSingleton ise , bunun yerine aşağıdakileri yapabilirsiniz:
class ExampleA
{
private $config;
public function __construct()
{
$this->config = Config->getInstance();
}
}
$exampleA = new ExampleA();
Öte ExampleByandan, Configher örneği için her zaman ayrı bir örneği alırsınız ExampleB.
Hangi sürümü uygulamanız gerektiği, uygulamanın şu örnekleri nasıl ele alacağına bağlıdır Config:
- Her örneği ise
ExampleXayrı bir örneğini olmalıdır Config, ile gitmek ExampleB;
- her bir örneği, eğer
ExampleXbir (ve yalnızca bir) örneğini paylaşacak Config, kullanıcı ExampleA with Config Singleton;
- örnekleri
ExampleXfarklı örnekleri kullanıyorsa Config, ile sopa ExampleA.
Neden dönüştürme Configbir içine Singleton yanlıştır:
Sadece Singleton desenini dün öğrendiğimi itiraf etmeliyim ( ilk tasarım desenleri kitabını okuyarak ). Saf bir şekilde bu örnek için devam ettim ve uyguladım, ancak birçok kişinin belirttiği gibi, bir yol başka bir şey (bazıları daha şifreli ve sadece "Yanlış yapıyorsun!" Dedi), bu iyi bir fikir değil. Yani, başkalarının benim yaptığımla aynı hatayı yapmalarını önlemek için, burada Singleton deseninin neden zararlı olabileceğinin bir özeti var ( yorumlara ve Google'da bulduğum şeylere dayanarak):
Örneğe ExampleAkendi başvurusunu alırsa Config, sınıflar sıkıca bağlanır. ExampleAFarklı bir sürümünü kullanmak için bir örneğe sahip olmanın bir yolu olmayacaktır Config(bazı alt sınıfları söyleyin). Bunu sağlamak için bir yolu olmadığı için ExampleAbir mock-up örneği kullanarak test etmek istiyorsanız bu korkunç .ConfigExampleA
Oradan öncül örneği biriniz, sadece biri olacak Configbelki tutar şimdi , ama her zaman emin olamaz aynı irade tutma gelecekte . Daha sonraki bir noktada, birden çok örneğinin Configisteneceği ortaya çıkarsa , kodu yeniden yazmadan bunu başarmanın bir yolu yoktur.
Bir-bir-bir-örneği Configtüm sonsuzluk için doğru olsa bile, Config(sadece tek bir örneği olsa da) bazı alt sınıflarını kullanmak isteyebilirsiniz . Kod doğrudan aracılığıyla örneğini alır çünkü Ama, getInstance()bir Configbir olan staticyöntem, alt sınıf almak için bir yolu yoktur. Yine, kod yeniden yazılmalıdır.
En azından sadece API'sini görüntülerken, ExampleAkullanımları Configgizlenecektir ExampleA. Bu kötü bir şey olabilir veya olmayabilir, ama kişisel olarak bunun bir dezavantaj gibi olduğunu hissediyorum; örneğin, devam ederken, Configdiğer sınıfların uygulanmasına bakmadan hangi sınıfların değişikliklerden etkileneceğini bulmanın basit bir yolu yoktur .
Aslında bile ExampleAbir kullanır Singleton Config başlı başına bir sorun değildir, hala bir görüş test noktasından bir sorun haline gelebilir. Singleton nesneleri, uygulamanın sonlandırılmasına kadar devam edecek bir durum taşır. Bu, birim testlerini çalıştırırken bir testin diğerinden izole edilmesini istediğiniz için bir sorun olabilir (yani bir testin gerçekleştirilmesi diğerinin sonucunu etkilememelidir). Bunu düzeltmek için, Singleton nesnesi her test çalıştırması arasında imha edilmelidir (potansiyel olarak tüm uygulamayı yeniden başlatmanız gerekir), bu da zaman alıcı olabilir (sıkıcı ve can sıkıcı bir durumdan bahsetmiyorum).
Bunu söyledikten, ben böyle bir hata sevindim burada gerçek bir uygulamanın uygulanmasında değil. Aslında, bazı sınıflar için Singleton modelini kullanmak için en son kodumu yeniden yazmayı düşünüyordum . Değişiklikleri kolayca geri alabilsem de (elbette her şey bir SVN'de saklanır), yine de bunu yapmak için zaman harcamıştım.