在PHP中管理长类文件的策略

spr*_*man 7 php oop refactoring

我有一堆功能,我想进入一个类.它们目前被分成几个相当长的文件.我不想有一个2500行文件,但据我所知,你不能使用include将一个类分成多个文件.从理论上讲,我可以将函数分组到不同的类中,但它们之间的关系非常紧密,我觉得它们属于一体,并且将它们分开会减少我希望从程序方法中脱离出来的一些实用工具. (使用共享属性,而不是几乎每个函数中的一堆参数).

我知道这有点模糊,但任何建议/指针?如果重要,那就是原型,因此代码管理的简易性优先于安全性和性能.

更新:让我看看我是否可以删除一些模糊性:

此类/函数集输出复杂形式的html.每个部分中有许多不同的部分和变体,具体取决于当前传递给函数的约5或6个参数.我希望将参数一次定义为类的属性,然后从所有节创建方法中访问它们.如果我使用子类,那些属性的值将不会被正确初始化,因此需要一个类.(嗯......除非我把它们定义为静态.我可能刚刚回答了我自己的问题.我将不得不看看是否有任何理由不起作用.)

我目前有很多功能,如:

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

所以我最初想象的是:

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
}
Run Code Online (Sandbox Code Playgroud)

现在我想的是:

// 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.
Run Code Online (Sandbox Code Playgroud)

或者我可能需要一个FormSection的抽象类,其中属性存在.

还有其他想法/方法吗?

Pet*_*ley 6

我将它们分成你想要的任意数量的类(或许多有意义的类),然后定义一个自动加载器以避免包含头痛.

编辑

好的,看到更多的代码后 - 我认为你正在接近子类错误.你有很多if反对意见$type,它告诉我是多态应该基于什么.

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
  }
}
Run Code Online (Sandbox Code Playgroud)


Tyl*_*ter 0

它们都在不同的文件中,这意味着它们足够不同,可以按文件分组。将它们构建到类中时只需采用相同的逻辑即可。我有一个用于构建页面的 Page 对象。从技术上讲,我的页面标题的 HTML 是页面的一部分,但我将其分离到 Page_HTML 类中,以保持我的理智,而不是创建巨大的类。

另外,我倾向于将子类(例如本例中的 Page_HTML)设为静态,而不是实例化它。这样我就可以访问 Page 类中的 $this 变量,但仍然将其分组到另一个类中。

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

class Page_HTML
{
    function getHeader()
    {
    }
}
Run Code Online (Sandbox Code Playgroud)