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, Config
tü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 Config
Singleton ise , bunun yerine aşağıdakileri yapabilirsiniz:
class ExampleA
{
private $config;
public function __construct()
{
$this->config = Config->getInstance();
}
}
$exampleA = new ExampleA();
Öte ExampleB
yandan, Config
her ö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
ExampleX
ayrı bir örneğini olmalıdır Config
, ile gitmek ExampleB
;
- her bir örneği, eğer
ExampleX
bir (ve yalnızca bir) örneğini paylaşacak Config
, kullanıcı ExampleA with Config Singleton
;
- örnekleri
ExampleX
farklı örnekleri kullanıyorsa Config
, ile sopa ExampleA
.
Neden dönüştürme Config
bir 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 ExampleA
kendi başvurusunu alırsa Config
, sınıflar sıkıca bağlanır. ExampleA
Farklı 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 ExampleA
bir mock-up örneği kullanarak test etmek istiyorsanız bu korkunç .Config
ExampleA
Oradan öncül örneği biriniz, sadece biri olacak Config
belki tutar şimdi , ama her zaman emin olamaz aynı irade tutma gelecekte . Daha sonraki bir noktada, birden çok örneğinin Config
isteneceği ortaya çıkarsa , kodu yeniden yazmadan bunu başarmanın bir yolu yoktur.
Bir-bir-bir-örneği Config
tü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 Config
bir olan static
yö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, ExampleA
kullanımları Config
gizlenecektir ExampleA
. Bu kötü bir şey olabilir veya olmayabilir, ama kişisel olarak bunun bir dezavantaj gibi olduğunu hissediyorum; örneğin, devam ederken, Config
diğ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 ExampleA
bir 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.