Statik kötü, ama ya Fabrika modeli?


13

Bir TDD projesindeyim, bu yüzden bu tür bir gelişmeyle ilgili iyi uygulamalara mümkün olduğunca bağlı kalmaya çalışıyorum. Bunlardan biri mümkün olduğunca statik ve küresel olmaktan kaçınmaktır.

Ben bu sorunla karşı karşıya: Ben bağlantılı "seçenekleri" (addnal "mikro-makaleler") olabilir bir nesne "makale" var.

Ben karşı üretken olmayacak veya çok fazla sorgu üretmek olmayacak iyi bir yaklaşım var nasıl anlayamıyorum çünkü temelde nesne başına 1 sorgu yapmak gerekecek kadar ayrıştırılmış bir durumda olurdu.

Gerçek perspektifime göre 3 seçenek görüyorum:

1) makale içinde inşa:

class Article
{
    //[...]
    public function getArrOption(){
        //Build an array of Options instance.
        //return an array of Options.
    }
}

Pro: Düz ileri

Sabit: Bakım: Makale nesnesi artık Option nesnesi için yapı mantığı içeriyor. Bu muhtemelen kod yinelemesine yol açacaktır.

2) Bir seçenek kullanmaFabrika

class Article
{
    //[...]
    public function getArrOption(){
        return OptionFactory::buildFromArticleId($this->getId());
    }
}

Pro: Yapı mantığı Makale sınıfının dışında değil

Const: "Statik alay etmek zor" kuralını çiğniyorum.

3) Tüm mantıkları ayırın.

//Build the array of Option instance in a controller somewhere, using a Factory:
$arrOption = OptionFactory::buildFromArticleId($article->getId());

Pro: Makale sadece kendi sorumluluğunu taşıyor ve seçenekleriyle "babası" bağlantısını umursamıyor. İşler gerçekten birbirinden ayrıldı

Const: Seçenekler'e her erişmem gerektiğinde Denetleyici içinde daha fazla kod gerekecektir. Bu, asla bir nesnenin içinde bir Fabrika kullanmamam gerektiği anlamına geliyor ve bana bu tür bir ütopik geliyor ...

Gitmenin en iyi yolu nedir? (Bir şey mi kaçırdım?) Teşekkürler.

Düzenle:

Sınıf içinde fabrikayı arayamazsam, tembel başlatma desenini de asla kullanamayacağımdan bahsetmiyorum bile ...


İlgili olup olmadığından emin değilim, ancak PHP'de kodlama yapıyorum, bu yüzden "uygulama" durum daha az. Bir oturum çerezinde saklanmadıysa, her sayfa arasındaki tüm verileri yeniden yüklemeliyiz. Bu , bir uygulama dilinde olduğu gibi her şeyi önceden yükleyemeyeceğimiz anlamına gelir .
FMaz008

@job: Bunun nedeni, bir yöntem içindeki statik bir çağrının birim sınaması sırasında değiştirilmesinin imkansız olmasıdır. Amaç bağımlılık enjeksiyonunu kullanmaktır. Ancak bir fabrika genellikle statiktir, bu nedenle enjekte edilemez.
FMaz008

Yanıtlar:


12
  1. Statik "kötü" değil, taşınamaz. Yine de alaycılığın mantıklı olmadığı yerlerde kullanabilirsiniz.

  2. Bu bir Fabrika kalıbı değildir, olmasa da bir Havuz kalıbına benzemektedir. Fabrika, aynı arabirim / taban sınıfıyla birden fazla sınıfınızın olduğu ve hangi sınıfın geri döneceğine karar veren mantığı ayırmak istediğiniz yerdir. Depo, veri havuzundan veri alır ve bu havuzun uygulanmasını soyutlar (Makalenin seçeneklerinin aynı DB'de, başka bir XML dosyasında, bir CSV dosyasında depolanıp depolanmadığını bilmesine gerek yoktur).

  3. Makale sınıfına yapıcıda buildFromArticle yöntemini çağırabileceği bir ObjectFactory (veya Havuz ya da her neyse) nesnesini verme olasılığını göz ardı ettiniz.

Benim PHP paslı, ama sanırım şöyle görünüyor:

class Article
{
    private $_option_repository;

    public function __construct($option_repository) {
        $_option_repository = $option_repository;
    }

    //[...]

    public function getArrOption(){
        return $_option_repository->buildFromArticleId($this->getId());
    }
}

Bence bu yukarıdaki tüm profesyonellerinizi yerine getiriyor.


Fabrika / Depo / Haritacı örneklerine sahip olmak sorun değil mi? Bir bağımlılık kapsayıcısına ya da başka bir şeye ihtiyacım olacak çünkü tüm fabrika / depo / haritacıyı bir nesne tarafından döndürülebilecek tüm nesne için enjekte etmemiz gerekiyorsa, bu çok hızlı bir şekilde çok şey yaptı. (Makale -> OptionGroup -> Seçenek -> Makale vb.)
FMaz008

1
Tamam değil, tercih edilir. Genellikle birden fazla sınıfta test edilecek kadar küçük olduğu tekrarlanan kodu kaldırmak için statik kullanım ayırıyorum. Ve evet, bir IOC / DI Konteyner hayatınızı çok daha kolaylaştıracak. Birini kullanın.
pdr

1

Kağıttan, asla statik yöntemlere ihtiyacınız olmadığını, soyut fabrikaların kafa karıştırıcı olduğu gösterildiğini ve çözüm olarak bağımlılık enjeksiyonuna hafif bir dil değişikliği önerdiğini iddia eden bir alıntı.

Örnekler ve sınıfları arasındaki sıkı bağlantı, kapsüllemeyi keser ve statik yöntemlerin küresel görünürlüğü ile birlikte testi zorlaştırır. Bağımlılık enjeksiyonunu programlama dilinin bir özelliği haline getirerek, statik yöntemlerden tamamen kurtulabiliriz. Aşağıdaki semantik değişiklikleri kullanıyoruz:

(1) Bir globalin her oluşumunu bir örnek değişkenine erişimle değiştirin;

(2) Örnek örneğinin, somutlaştırıldığında nesneye otomatik olarak enjekte edilmesine izin verin.

"Seuss: Hassas yapılandırılabilirlik için statik yöntemlerden sorumlulukların ayrılması"

Wayback Makinesi Bağlantısı


3
Bu bağlantı soruyu cevaplayabilse de, cevabın temel bölümlerini buraya eklemek ve bağlantıyı referans olarak sağlamak daha iyidir. Bağlantı verilen sayfa değişirse, yalnızca bağlantı yanıtları geçersiz olabilir.
gnat
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.