лучший способ рефакторинга моей формы (процедурный к упс?) - PullRequest
4 голосов
/ 18 декабря 2009

(Примечание: это относится к этому вопросу , но я думаю, что он мог бы быть написан более четко, поэтому я пытаюсь снова - мое обновление помогло только в ограниченной степени.)

Я унаследовал некоторый код, который создает сложную форму с многочисленными разделами и множеством возможных представлений, в зависимости от ряда параметров. Я работал с ним некоторое время, и, наконец, у меня появилась возможность подумать о некотором ре-факторинге. В настоящее время он написан процедурно, с кучей функций, которые выглядят так:

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

Передача этих параметров неприятна, поэтому я начал писать такой класс:

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;
    // 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.
}

Проблема в том, что процедурные функции разбиты на несколько файлов (для групп разделов), и если я объединю их все в один файл класса, я смотрю на 2500 строк, что кажется громоздким. Я подумал о нескольких решениях:

  1. продолжай жить с неприятными параметрами и делай что-нибудь еще с моим временем:)
  2. с файлом из 2500 строк
  3. создать отдельный класс для каждой группы секций, который каким-то образом «знает» значения этих параметров

Если я сделаю № 3, я подумаю о двух основных подходах:

  1. передать объект MyForm как один параметр
  2. создайте класс FormSectionGroup со статическими свойствами, которые устанавливаются в MyForm, затем в файлах групп каждый класс расширяет FormSectionGroup и автоматически получает доступ к текущим значениям этих параметров.

1), вероятно, проще в настройке, и как только я окажусь внутри get_section_A(), скажу ли я $this->type или $myForm->type, это не так уж и отличается, но это не совсем ООП. (На самом деле, я мог бы сделать это, не переходя на ООП-подход).

Есть ли другие подходы? Мысли о том, что лучше?

Ответы [ 4 ]

1 голос
/ 19 декабря 2009

Я не хотел бы ничего больше, чем написать длинное объяснение того, как это сделать, но мне немного лень. Однако у меня достаточно энергии, чтобы вместо этого указать вам Zend_Form из Zend Framework. Могут быть некоторые зависимости, чтобы заставить его работать должным образом (Zend_View, Elements, Decorators), но когда они у вас есть, он обрабатывает ситуации такого типа весьма изящно.

0 голосов
/ 20 декабря 2009

Если у вас есть время поработать над номером 3, вы, вероятно, станете самым счастливым в долгосрочной перспективе. Лично у меня нет времени на работу, чтобы очень часто проводить рефакторинг, и поэтому я, вероятно, буду вынужден выбрать # 1. # 2 звучит как худшее из обоих миров для меня. Много работы, чтобы получить код, который вам не нравится.

0 голосов
/ 19 декабря 2009

В последнее время много занимаясь программированием на Какао, я склонен рассматривать вещи в терминах MVC-pattern (Model-View-Controller). Следовательно, я бы посмотрел на форму как на контроллер ее различных разделов.

Каждый объект раздела должен отвечать за отслеживание его статуса, значений и того, должен ли он отображаться. Или, если быть точным, section_model будет заботиться о значениях (значения по умолчанию, проверка и т. Д.), Section_view будет заботиться об отображении (или нет) частей раздела, а section_controller будет посылать отслеживание статуса раздела и сообщить результаты в объект формы.

Объект формы должен создавать экземпляры контроллеров секций, указывать им отображать, скрывать или что-либо еще и получать отчеты о состоянии. Объект формы, действительно действующий как контроллер, может затем решить, когда форма будет полностью заполнена. У вас может быть объект form_model для сохранения собранных данных, или, возможно, вы бы предпочли, чтобы объекты section_model принимали участие в этом. Потребуется некоторое время, чтобы понять, как взаимодействуют различные объекты, но из опыта я знаю, что если вы будете дисциплинированы в проектировании ваших объектов (ключ: что является ответственностью объекта, а что нет), вы получите лучшее обзор и ваш код будет легче обновить. Как только вы обнаружите, что улучшения начинают возникать естественным образом, вы на правильном пути.

0 голосов
/ 18 декабря 2009

Я думал об этом, когда писал в своем предыдущем вопросе - эта проблема пахнет шаблоном декоратора .

Это будет не маленькая задача, хотя. Но я думаю, что вы получите удивительное чувство удовлетворения / выполнения, как только вы это сделаете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...