Işbirliği yapmayan sınıf hiyerarşisi ile Polimorfizmi

3 Cevap php

Ben hepsinin ortak özellikleri ve yöntemleri paylaşmak çünkü ortak bir atadan uzanan çeşitli sınıflar var bir senaryo var. Bu sınıflar (Grup A) yarısı diğer yarısı (B Grubu) tarafından paylaşılmayan bir özellik içerir, bu nedenle A Grubu her bir sınıf açıkça bu özelliği yerine üst sınıf bildirir.

örneğin

class parent
{

}

class child1 <and child2, and child3> extends parent
{
    protected $specialProperty;
}

class child4 <and child5, and child5> extends parent
{
    // no "$specialProperty"
}

Ben o $specialProperty üzerinde hareket uygulamak için gereken bazı davranışları var. Doğal olarak, bir üst sınıfta bu koymak ve sadece bir kez yapmak istiyorum, ama $specialProperty çocuk sınıflar tüm yok.

Bir seçenek $specialProperty bildirir ve gerekli davranışı uygulayan bir ara, soyut bir sınıf oluşturmak için, ama ben bir kaç nedenden dolayı bunu yapmak için isteksiz değilim:

  1. Bu senaryo daha yakında olacak. Ben o zaman ne yapacağım? 5 veya 6 farklı kabzımal bu işlevleri her biri için soyut sınıfları oluşturmak?
  2. Sınıf hiyerarşisi zaten derin üzerinde yaklaşık 5 düzeyleri {[(0)}]. Ben gerçekten sınırlı gereklerine hastefully tasarlanmıştı bir az daha ideal sınıf hiyerarşisi telafi etmek için daha fazla ve daha fazla katman yaratmak olmalıdır?
  3. En azından bildiğim kadarıyla PHP ile ilgili olarak, miras değil pek çok katmanları da performans sorunlarına yol açacak?

Başka bir seçenek şunları yapmaktır:

class parent
{
    public function functionThatTheAppWillCallAutomatically()
    {
       if ( property_exists($this, 'specialProperty') )
       {
           // do stuff with specialProperty
       }
    }
}

"Şeyler" $specialProperty sahip çocuk sınıflar tarafından yürütülen ve olmayanları tarafından atlanır olacaktı. I hate bu çözüm olsa da sadece yanlış ve bana özensiz görünüyor çünkü. Benim görüşüme göre, ebeveyn ne çocuğun özelliklerine göre edersiniz (halt, muhtemelen hatta çocuğun var olduğunu bilmek gerektiğini karar olmamalı - olmadığını ilk etapta çocuk sınıf için nedeni ?)

Kısacası, ben en kötü bu iki seçenekten hangisinin emin değilim, ya da daha iyi bir olasılık varsa. Ben endişeyle önerileri bekliyorum.

Teşekkürler!


EDIT:

Ben bu özel işlevselliğini uygulamak için aşağıdakileri yaparak sona erdi.

class archivalDecorator extends decoratorBase /* decoratorBase just has constructor and the object property */
{
    public function archive()
    {
        if ( !$this->object->archive() )
        {
            return false;
        }

        if ( property_exists($this->object, 'specialProperty') )
        {
            // do extra stuff here that involves "specialProperty"
        }

        return true;
    }
}

Bu şekilde, benim tüm nesnelerin aynı arşiv iş akışını gerçekleştirmek, ama özel bir davranışı gerektiren sınıflar beni hala bu özel durumlar için hiyerarşisinde alt sınıflarından onlarca uygulamaya gerek kalmadan gerçekleştirebilirsiniz.

Hala property_exists(...) özel bir davranış gerekli olup olmadığını belirlemek ya da değil kullanıyorum rağmen, ben üst sınıf içinde yapmıyorum, çünkü bu artık Tamam olduğunu düşünüyorum. $specialProperty bir kamu malı olduğunu, bu nedenle orada dış sınıflar bundan haberi olmamalı hiçbir neden yok, ama bir şey sadece üst sınıf $this kullanarak bir çocuk sınıf içinde bu özellik için denetleme hakkında yanlış hissettim .

Ben kavramı misapplied değil umuyoruz.

3 Cevap

Bu sınıfları ne yaptığını bilmek olmadan söylemek gerçekten zor, ama sorunları (birden fazla alt ağaçlar, isteğe bağlı çapraz ağaç işlevselliği, vb derin sınıf hiyerarşileri), bazı decorator pattern için ihtiyaç göstergesidir.

Ben PHP ile çok aşina değilim ve sınıf hiyerarşisinin herhangi bir özellikleri yok, ama ben sınıf hiyerarşisinin derinliği hakkında endişeleri hakkında yorum yapmak istiyorum.

Modellediğiniz ne olursa olsun derin bir sınıf hiyerarşisi ile sona özelliklerinin açısından yeterince heterojen ise, yapay bir kapak koyarak ve birçok kabzımal "beş düzeyleri Tamam ama altı değil", ya da "x diyerek hiçbir anlamı yoktur çok fazla ". Soyut bazı farklılıklar değil, dolayısıyla aynı "denklik sınıfları" içine birden çok örneğini koyarak, tüm bunları temsil edebilir sürece, bir yere bölünmüş modellemek zorunda ve bu gibi herhangi bir iyi olabilir. Eğer türü hiyerarşisi bunu yapmazsanız, siz yazın çek veya ekstra özellikleri ile bitirmek olabilir.

Bazı özelliklerin varlığı üst üste çünkü, çok karmaşık bir hiyerarşi ile kendinizi buluyorsunuz eğer PHP rahatlıkla desteklenir ise, sen, dekoratör deseni gibi çoklu kalıtım (veya birden fazla arayüz uygulaması) bakmak isteyebilirsiniz.

Ok, so you have a special property that only exists in some class and you have a method that has to act on this special property but you don't know where to put it?
What about in the class you define the special property?

class child1 <and child2, and child3> extends parent
{
    protected $specialProperty;

    public function doSomethingWithSpecialProperty() {

   }
}

Başka bir seçenek ebeveynin yöntemini geçersiz olacaktır:

class child1 <and child2, and child3> extends parent
{
    protected $specialProperty;

    public function functionThatTheAppWillCallAutomatically() {
        parent::functionThatTheAppWillCallAutomatically();
        // do other stuff
    }
}

Ayrıca tutucu olarak bir şekilde davranan bir boş yöntem oluşturmak ve çocuk sınıflar gerektiğinde bunu uygulayabilirsiniz:

class parent
{
    public function functionThatTheAppWillCallAutomatically()
    {
       $this->extraStuff();
    }
    protected function extraStuff(){};
}


 class child1 <and child2, and child3> extends parent
 {
    protected $specialProperty;

    protected function extraStuff() {
        echo $specialProperty,
    }
 }

Aksi takdirde tekrar tasarımı hakkında düşünmek zorunda kalabilirsiniz.