Birçok dosya içine büyük bir işlev üstlenmeden

3 Cevap php

Ben daha önce geliştirilen ediyorum kod "bit" refactor çalışıyorum. Temelde, projenin etkin bir XSLT nasıl kullanılacağını bilmeden benim cevap oldu, bu yüzden ben PHP bir XML dönüşüm sistemi geliştirdi. Program, bir XML dosyasının etiketler aracılığıyla okur ve HTML dönüştürmek için bu satırlar boyunca bir şey yapar:

private function getTemplate(...) {
    switch ($nodeName) {
        case "a" :
            // code here to generate a link tag
            break;
        case "box" :
            // code here to generate the divs and whatnot to create a box
            break;
        case "ref" :
            // look up an external reference file and include a bibliography
            break;
        default :
            // do the default thing
    }
}

Hepsi benim anahtara 26 şube ile sona erdi dışında, büyük çalışıyordu ve o zamanlar blok kodunun 1000 yılı hatları oldu geçiş. Söylemeye gerek yok, bu bakım biraz daha zorlaştırdı.

Ben şimdi ne yaptık üzerinden kendi dosyası (adında "a.php", "box.php", "ref.php" ...) ve include her bir dalın kod çekin için Bu dosya her zaman:

if (file_exists("templates/$nodeName.php")) {
    include "templates/$nodeName.php";
} else {
    // do the default thing
}

Yine, bu işleri, ama kıyaslama% 50 oranında işlem kez yavaşladı olduğunu göstermektedir. Ben orada 4000'e kadar şimdi nerede include s şimdi yapılıyor çünkü bu olduğunu varsayarak yaşıyorum.

Ne düşündüğünü bir işlev içine her şablon için kod koymak oldu, ve işlevi daha sonra ilan dosyasını içerir ve daha sonra işlevi çalıştırmak değil ise - ki tek sorun mevcut kod ile yazılmış olmasıdır $this, vb kullanan orijinal fonksiyon kapsamı,

, Burada benim için herhangi bir tavsiye var mı: - Bu kod (o anında bitmedi bu sadece depolanan statik HTML dosyalarının içine XML işler gibi) gerçek zamanlı olarak çalıştırmak olduğu göz önüne alındığında?

3 Cevap

ihtar: Sadece XSLT'yi kullanamazsınız eğer ben PHP bilmiyorum, ama ben google can ve ben büyük switch ifadeleri daha iyi işlev işaretçileri gibi, bu yüzden ...

... Bir seçenek html düğümün etiket adını dahil sizin 'işçi' işlevler için, örneğin bir adlandırma kuralı benimsemek olacaktır _converter, tüm işlevleri içeren ve benzeri bir şey ile switch deyimi değiştirin:

private function getTemplate(...) 
{
    $func = $nodeName + "_converter";
    if (function_exists($func))    //see if function is defined, somehow...
    {
        $func();    //call conversion function (pass whatever is needed)
    }
}

Böyle bir şey deneyin:

//utils.php
function handle_box($node)
{
//...
}

function handle_link($node)
{
//....
}
?\>

sonra:


require_once 'templates/utils.php';


function getTemplate()
{
  switch($node)
  {
      case "a" :
        handle_link($node,$otherParams);
      break;
  }
}

}

Temelde bu kendi fonksiyonu her bir düğüm için tüm işlevselliği refactors. Buradan daha genel çözüm üzerinde çalışabilirsiniz. Size orijinal vardı ne çok benzer ama switch / case ifadeleri onlara içinde kod bir ton olmadan çok daha yönetilebilir olacaktır. Eğer gerekli olduğunu düşünüyorsanız o zaman potansiyel Stratgy design pattern uygulanması doğru bakabilirsiniz.

XSLT içine kendini alma ve üstlenmeden sorusuna odaklanarak olmadan: Zaten farklı stratejileri adil bir miktar kabul var. Ben sizin için işe yarayabilecek bir optimizasyon zaten tecrübe yaklaşımların birinde ucu, ve bir diğer yaklaşım sunacak.

Eğer çok sayıda dosya dayanarak,% 50 performans azalma olduğunu söyledi zaman. Ben PHP Op-kodu önbellek etkin değil götürün. Bunu, ve% 50 kaybetmek ortadan gerektiğini yapmak.

Diğer bir yaklaşım, ben NodeProcessor ya da öylesine bir temel sınıf oluşturma öneririm. Ve sonra ANodeProcessor, RefNodeProcessor, ... vs her düğüm için yeni bir sınıf oluşturmak

processTag: Alternatif olarak, sadece şeklinde yöntemleri içeren bir sınıf NodeProcessor oluşturabilir. Daha sonra:

  1. Sen $this->processNode($tag); çağırabilirsiniz
  2. Bir o yöntemde: $name = 'process'. $tag;
  3. Daha sonra: return $this->nodeProcessor->{$name};
  4. NodeProcessor hayır processTag yöntemle tanımlanmış olan etiketleri için "varsayılan şey" yapmak için __call() yöntem olmalıdır.

Yine, op-kod önbelleğe eklemek için unutmayın.