php uzun sınıf dosyaları yönetmek için stratejiler

6 Cevap php

Ben bir sınıfa taşımak istediğiniz fonksiyonları bir sürü var. Onlar şu anda oldukça uzun dosyaların bir çift bölünmüş demektir. Ben bir 2500 satır dosya tercih ediyorum, ama bildiğim kadarıyla söyleyebilirim, birden fazla dosya içine bir sınıf bölmek dahil kullanamazsınız. Teoride, ben grup farklı sınıflar işlevleri olabilir, ama bunlar yakından onlar birbirine ait gibi hissediyorum yeterince ilgili konum ve bölme onları uzak bir usul yaklaşımdan hareket almak için umuyorum yarar bazı azaltacak (yerine neredeyse her fonksiyonu olan parametrelerin bir demet daha ortak özelliklere sahip).

Bu biraz belirsiz olduğunu biliyorum, ama herhangi bir öneri / işaretçiler? Bu konularda, bu bir prototip için, yani kod yönetim kolaylığı, güvenlik ve performans önceliklidir.

UPDATE: Ben belirsizlik bazı kaldırabilirsiniz bakayım:

Fonksiyonları bu sınıf / set karmaşık bir form için html çıktılar. Şu fonksiyonları içine geçirilir, yaklaşık 5 veya 6 parametrelerine bağlı olarak, her bölüm içinde bir çok farklı bölümleri ve varyasyonları vardır. Ben sınıfın özellikleri olarak bir kez parametrelerini tanımlamak ve sonra bölüm oluşturma yöntemleri içindeki bütün onlara erişmek için umuyordum. Ben alt sınıfları kullanıyorsanız, bu özelliklerin değerleri bir sınıf dolayısıyla arzusu, düzgün başlatılmamış olmayacaktır. (Hmm. .. Ben statik onları tanımlamak sürece. Ben olabilir sadece kendi sorusunu yanıtladı. Ben işe yaramaz herhangi bir neden olup olmadığını görmek için bakmak gerekir.)

Şu anda gibi fonksiyonları bir karmaşa var:

get_section_A ($type='foo', $mode='bar', $read_only=false, $values_array=array()) {
    if ($this->type == 'foo') { }
    else ($this->type == 'foo') { }
}

Yani başlangıçta hayal gibi bir şey oldu:

class MyForm {
    public $type;          // or maybe they'd be private or 
    public $mode;          // I'd use getters and setters 
    public $read_only;     // let's not get distracted by that :)
    public $values_array;
    // etc.

    function __constructor ($type='foo', $mode='bar', $read_only=false, $values_array=array()) {
        $this->type = $type;
        // etc.
    }

    function get_sections () {
        $result = $this->get_section_A();
        $result .= $this->get_section_B();
        $result .= $this->get_section_C();        
    }      

    function get_section_A() { 
        if ($this->type == 'foo') { }
        else { }
    }
    function get_section_B() {}
    function get_section_C() {}
    // etc. for 2500 lines
}

Şimdi şöyle bir şey düşünüyorum:

// container class file
class MyForm {
    static $type 
    static $mode
    static $read_only
    static $values_array
    // etc.

    function __constructor ($type='foo', $mode='bar', $read_only=false, $values_array=array()) {
        MyForm::$type = $type;
        // etc.
    }

    function get_sections () {
        $result = new SectionA();
        $result .= new SectionB();
        $result .= new SectionC();
    }      
}

// section A file
class SectionA extends MyForm {
    function __constructor() { 
        if (MyForm::$type == 'foo') { }
        else { }
    }

    function __toString() {
        // return string representation of section
    }
}

// etc.

Ya da muhtemelen özelliklerini yaşamak FormSection soyut bir sınıf gerekir.

Diğer fikirler / yaklaşımlar?

6 Cevap

Genellikle böyle bir şey yapın:

class one
{
    public function __get($key)
    {
    	// require __DIR__ / $key . php
    	// instanciate the sub class
    }

    public function mainMethod()
    {
    }
}

class one_subOne extends one
{
    public function otherMethod()
    {
    }
}

class one_subTwo extends one
{
    public function anotherMethod()
    {
    }
}

$one->mainMethod();
$one->subOne->otherMethod();
$one->subTwo->anotherMethod();

Ben (ya da çok mantıklı değil) istediğiniz gibi birçok sınıflara onları bölmek istiyorum ve daha sonra define an autoloader dahil baş ağrısı ortadan kaldırılmasıdır.

EDIT

Tamam, senin kod daha gördükten sonra - Ben yanlış altsınıflara yaklaşıyor düşünüyorum. Sen that polimorfizmi dayanması gerektiğini ne olduğunu bana işaret $type karşı if tabloların, bir sürü var.

abstract class MyForm
{
  protected
      $mode
    , $read_only
    , $values
  ;

  public function __construct( $mode, $read_only=false, array $values = array() )
  {
    $this->mode      = $mode;
    $this->read_only = (boolean)$read_only;
    $this->values    = $values;
  }

  abstract function get_section_A();

  abstract function get_section_B();

  abstract function get_section_C();

  //  final only if you don't want subclasses to override
  final public function get_sections()
  {
    return $this->get_section_A()
         . $this->get_section_B()
         . $this->get_section_C()
    ;
  }
}

class FooForm extends MyForm
{
  public function get_section_A()
  {
    // whatever
  }

  public function get_section_B()
  {
    // whatever
  }

  public function get_section_C()
  {
    // whatever
  }
}

Bildiğim kadarıyla görünüm söz konusu bina olarak, size CompositeView pattern denemek isteyebilirsiniz.

Burada PHP bakmak nasıl küçük bir örnek. View::$html diskten html yükleyebilirsiniz Şablon sınıfta kapsüllü ve değişkenleri enjekte sağlar, kaçan çıktı, vb kolları olduğunu, bu örneğin uğruna, Pretend

interface IView {
    public function display();
}

class View implements IView {
    public $html = ''; 

    public function display() {
        echo $this->html;
    }   
}

class CompositeView implements IView {
    private $views;
    public function addPartial(IView $view) {
        $this->views[] = $view;
    }   
    public function display() {
        foreach ($this->views as $view) {
            $view->display();
        }   
    }   
}

IView arayüzü için nedeni diğer kompozit manzaralı kompozit görüşlerini oluşturmak için izin vermektir.

Başlık, gövde ve altbilgi: Yani şimdi üç parça ile bir form düşünün.

class HeaderView extends View {
    public function __construct() {
        $this->html .= "<h1>Hi</h1>\n";
    }   
}

class BodyView extends View {
    public function __construct() {
        $this->html .= "<p>Hi there.</p>\n";
    }   
}

class FooterView extends View {
    public function __construct() {
        $this->html .= "<h3>&copy; 2012</h3>\n";
    }   
}

(Yine, sadece kamu değişken içine HTML yazmak ve çıkış kendinizi kaçan idare etmem. Olasılıkla bir şablon dosya başvuru ve şablonun arayüzü üzerinden veri kayıt ediyorum.)

Ardından, tüm koymak için birlikte gitmek istiyorum:

$view = new CompositeView();
// here you would make decisions about which pieces to include, based
// on your business logic.  see note below.
$view->addPartial(new HeaderView());
$view->addPartial(new BodyView());
$view->addPartial(new FooterView());
$view->display();

Yani şimdi görünümler oluşabilir ve parçaları yeniden, ama koşulları ve birçok farklı olası sonuçları çok şey var, özellikle kolayca, onları inşa koduyla bir karmaşa yapabilirsiniz (yapmak gibi geliyor.) İşte böylece durumda, Strateji desen muhtemelen bazı yardımcı olacaktır.

Zaten okumadıysanız UncleBob's SOLID article, herşeyden önce bunu! En azından tek sorumluluk prensibi. Ben de bir noktada Joshua Kerievsky tarafından Patterns Refactoring okuma tavsiye ederim.

Onlar dosyası tarafından grubuna kadar farklı olduğu anlamına gelir, farklı dosyalarda tüm vardır. Sınıflara onları oluştururken sadece aynı mantık alır. Ben sayfa bina ile ilgilenen bir Page nesnesi var. Teknik olarak benim sayfa başlığında için HTML sayfasının bir parçası, ama benim aklı korumak ve dev sınıfları oluşturmak için değil bir Page_HTML sınıfa ayırmak.

Ayrıca, ben bunun yerine başlatmasını, bu durumda statik Page_HTML gibi sub_classes, yapmak eğilimindedir. Ben Page sınıfında bu değişkenler $ erişmek, ama yine de başka bir sınıfa grup onu edebilirsiniz.

class Page
{
    function buildPage($content)
    {
        $content = Page_HTML::getHeader() . $content;
    }
}

class Page_HTML
{
    function getHeader()
    {
    }
}

This class/set of functions outputs the html for a complex form.

Neden denklemden PHP kaldırmak değil? Bu dosya sistemi ile kolayca yapılabilir görünümleri düzenlemek için PHP kullanıyorsanız görünüyor. Sadece mümkün olduğunca az PHP ile HTML görüşlerini yazmak. Sonra görüşlerini isteklerini eşleştirmek için PHP kullanabilirsiniz. Ben PHP ile formları işleme varsayarak yaşıyorum, ve bunu devam edebilir. Onlar sadece kabul doğrulama ve muhtemelen girdi tasarruf çünkü Ancak, sınıflar çok daha küçük olacak.

Eğer OOP yapmak istiyorsanız, endişeleri ayırmak ve bunları uygun sınıflarda çevreliyor. Onları uzatarak veya bileşiminde veya daha iyi toplama yoluyla bunları birleştirin. Herhangi bir yinelenen kodu kaldırın. Kendini tekrar Dont.

Senin durumunda, sizin specific formunda ilgili şeyler yaklaşık any Formu olduğunu şeyler ayrı. Herhangi Formu için kullanılan kod genel bir form sınıfının içine yerleştirmek istediğiniz koddur. Daha sonra projelerde bu yeniden kullanabilirsiniz. Çok karmaşık bir form sınıfının bir Örneğin, kontrol Zend_Form.

/ A belirli bir form ilgili kodunuzda bir şey jenerik formu uzanan o kendi bir sınıf içine alır. Kodunuzda verilen type İşletmeden varsayarsak, büyük olasılıkla {[gelen karmaşıklığı ortadan kaldıracak (yerine tek-tip-uyan tüm-formu) birden fazla özel amaçlı formu sınıfları, sonunda olabilir (1)]} yöntemleri ve formun belirli bir tip gibi bakmak ve yapmak gerekiyordu ne konsantre çünkü korumak için kodunuzu bir çok kolaylaştıracak.

Orada kod var eğer Son olarak, bu form içinde form için veri getirir veya aksi takdirde direk, bina formu çıkarın ve ayrı bir sınıf haline getirerek ilgili değildir. Eğer endişeleriniz ayrı ve form sınıfların 'endişe veri ya da bir şey olsun, bir form değil, inşa etmektir istiyorum, unutmayın. Verileri kurucu veya özel bir setter ile forma aktarmak istediğiniz bir şeydir.