PHP bir üst sınıf üzerinden birden fazla sınıflar acess nasıl

4 Cevap php

Parametreleri göndermek ve (bir ön denetleyicisi olarak davranan) benim index dosyası üzerinden gelen arama işlevleri, ben örneğini PageBuilder hangi adında bir sınıf var diyelim. Head, Body ve Foot, {[(0) tarafından erişilen: PageBuilder sınıf ile ilişkili üç alt sınıfları vardır }] için temelde onları soyutlamaya olan index.

Yani teoride örneğini PageBuilder ve PageBuilder parçası sanki diğer sınıflara tam erişime sahip olabilir.

Nasıl böyle bir tasarım sınıfları, soyut sınıflar ve arayüzler herhangi bir kombinasyonunu kullanarak PHP5'ta uygulayabilirsiniz?

Ben yukarıdaki PHP5 ile mümkün olduğunu sanmıyorum, PHP kendi sınırlamaları vardır ille çünkü ama benim uygulama tasarımı yanlış şekilde gidiyorum belki çünkü.

PHP OOP Ortak örnekler beni daha karmaşık bir tasarım yapısı nasıl anlamanıza yardımcı olmak için yeterli değildir.

Teşekkürler.

4 Cevap

Diğer cevapların bazıları doğru yolda. Eğer içine çalıştırıyorsanız sorun PageBuilder class çok yapıyor olmasıdır. Sadece isim bunu yapmak için çalışıyoruz ne için yanlış geliyor. A PageBuilder bir Page bir araya parça bir demet araya bir şey gibi geliyor. Kullanıcının bu parçalar Section diyelim. Cevaplar birkaç değindim gibi Sonra, ne yapmak istiyorsun, kullanım bileşimidir.

Kalıtım sık sık Section sınıfları PageBuilder sınıfını genişletmek durumunda olduğu gibi, bir is-a ilişki olarak tarif edilir, daha sonra Section bir {olduğunu [(2)]}. Ne istediğiniz olsa PageBuilder sınıfında olduğu gibi bir has-a ilişkisi gemi, bir (veya birçok) Section (ler) sahiptir. Bir has-a ilişkiyi ihtiyacınız olduğu zaman, yerine miras dışında kompozisyon doğru bakıyor olmalıdır.

Yani burada sınıf hiyerarşisi olabilir:

abstract class PageBuilder
{
    //@var Section
    public $header;

    //@var Section
    public $body;

    //@var Section
    public $footer;

    public function render()
    {
        echo $this->header.$this->body.$this->footer;
    }
}

class Section
{
    protected $content;
}

class LoginPage
    extends PageBuilder
{
    public function __construct()
    {
        $this->header=new Section(...);
        $this->footer=new Section(...);
        $this->body=new Section(...);
    }
}

Bu noktada, gerçekten tür bir boktan MVC yaparak sistemi tekerleği yeniden icat demektir. Bu (yerine öğrenme için daha) bir proje için ise, PHP için MVC çerçeveler birini kullanarak düşünmelisiniz. (I Kohana tavsiye, ama several questions Yığın taşması iyi PHP sürümleri ile ilgili bulunmaktadır.) Eğer bu tür şeyler düşünüyorsanız, MVC muhtemelen büyük olmayacak sizin için sıçrama.

Ben burada ne anlamak itibaren kompozit desen kullanabilirsiniz

http://en.wikipedia.org/wiki/Composite_pattern

Bazı standartlar "generatePage" gibi işlev ile kontrolör endeksi, bir arayüz IPageBuilder (veya benzer bir isim) uygulayan bir nesneye sadece erişimi vardır. Bu nesne, gerçekte tip IPageBuilder diğer nesne içeren konteyner bazı tür olacaktır. Bu yapraklar nesnenin bazı Başkanı gibi sayfanın alt bölümüne, Vücut ve Ayak kurmak mümkün olacaktır. Bu yaprak nesnenin her bir sınıfın farklı olurdu, ama onlar IPageBuilder arabirimini uygulamak olacaktır. Senin dizin nesne çağrısı "generatePage", konteyner sırası sırayla HTML işleme ilgilenir onun yaprak nesnelerin her biri "generatePage" yöntemi, arayacak zaman.

Beden sınıf çok büyük hale gelirse, bu yaklaşımı kullanarak, her zaman IPageBuilder arayüz, örneğin bir blog yazısı Vücut bir Makale nesne ve bir CommentList nesne oluşur olabilir uygulayan bir kap içine açabilirsiniz. Gövde nesnesi sonra sadece kendi çocukları nesne "generatePage" yöntemini yaymak olacaktır.

Lütfen IPageBuilder nesnesi oluşturmak için, bir fabrika desenleri kullanabilirsiniz

http://en.wikipedia.org/wiki/Factory_method_pattern

Tüm dürüstlük, benim HTML üretmek için geçmişte yaklaşım bu tür denenmiş ve onları tür overkill bulduk. Benim önerim Smarty gibi, bunun yerine bir çiftleşmiş motoru kullanmak olacaktır. O ^ ^ yaparsanız tasarımcısı seni seviyorum (veya daha az nefret) olacaktır.

http://www.smarty.net/

Eğer çok zor olduğunu, PHP arayüzleri değil nasıl kullanılacağını bilmek istiyorum ...

http://ca.php.net/manual/en/language.oop5.interfaces.php

Eğer doğru anlamak Yani Baş, gövde ve ayak otomatik PageBuilder çocukları olarak inşa etmek istiyoruz?

Belki bu yapabileceğini yolları bir çift vardır.

1) sınıfları tutmak için PageBuilder içinde değişken oluşturma ve __ çağrı yöntemi kullanın

class PageBuilder{
   private _head;
   private _body;
   private _foot;

   function __construct(){
       $this->_head = new Head();
       $this->_foot = new Foot();
       $this->_body = new Body();
   }

   function __call($name, $args){
       if(method_exists($this->_head, $name)) call_user_func_array(array($this->head, $name), $args);

       // Repeat for other classes.

   }

}

Iki sınıf aynı yöntemi kazanır gelip sonra ilk paylaşıyoruz burada sorun besbelli olmak. Muhtemelen oldukça kolay işlev adı dayalı bir sınıf almak için değiştirebilir.

2) her şeyi zincirleyin.

Abstract class Page{
}

class Head extends Page{
}

class Body extends Head{
}

class Foot extends Body{
}

class PageBuilder extends Foot{
}

Onun biraz kesmek ya da yolu, sadece tür çalışması yapmak zorunda.

PHP sadece (sırayla başka bir ana sınıfı, vb uzatabilirsiniz) bir üst sınıfı genişletmek için olanak sağlar. Hiçbir arayüzleri, çoklu arabirimler size C + + geldiğince gelen işlevleri veya özellikleri miras alamaz anlamı vardır.

Gibi, muhtemelen daha böyle bir şey yapmanız gerekir:

class PageBuilder {
    protected Head, Body, Foot;

    public function __construct($request) {
        $view = $this->getView($request);

        $this->Head = new PageSection('head.tpl');
        $this->Body = new PageSection($view);
        $this->Foot = new PageSection('foot.tpl');
    }

    private function getView($request) {
        // @todo return the template filename/path based upon the request URL
    }
}

class PageSection {
    private $template;

    public function __construct($template) {
        $this->template = $template;
    }

    public function render() {
        // @todo process and output the $this->template file
    }
}