Я разрабатываю класс, который определяет очень сложный объект с тонны (50+) в основном необязательных параметров, многие из которых будут иметь значения по умолчанию (например: $type = 'foo'; $width = '300'; $interactive = false;
). Я пытаюсь определить лучший способ настроить конструктор и переменные экземпляра/класса, чтобы иметь возможность:
- упростить использование класса
- упростить автоматическую документацию класса (т.е. используя phpDocumentor)
- code this elegantly
В свете вышеизложенного я не хочу передавать конструктору массу аргументов. Я передам ему один хэш, содержащий значения инициализации, например: $foo = new Foo(array('type'=>'bar', 'width'=>300, 'interactive'=>false));
В терминах кодирования класса я все еще чувствую, что лучше...
class Foo {
private $_type = 'default_type';
private $_width = 100;
private $_interactive = true;
...
}
... потому что я считаю, что это облегчит создание документации (вы получите список свойств класса, который позволяет пользователю API знать, с какими "параметрами" они должны работать), и он "чувствует" себя как право способ сделать это.
Но тогда вы сталкиваетесь с проблемой сопоставления входящих параметров в конструкторе с переменными класса и без использования таблицы символов, вы получаете подход "грубой силы", который мне поражает цель (хотя я открыты для других мнений). Например:.
function __construct($args){
if(isset($args['type'])) $_type = $args['type']; // yuck!
}
Я рассмотрел создание одной переменной класса, которая сама по себе является ассоциативным массивом. Инициализация этого будет очень простой, например:
private $_instance_params = array(
'type' => 'default_type',
'width' => 100,
'interactive' => true
);
function __construct($args){
foreach($args as $key=>$value){
$_instance_params[$key] = $value;
}
}
Но это похоже на то, что я не использую встроенные функции, такие как частные переменные класса, и похоже, что создание документации не будет работать с этим подходом.
Спасибо, что прочел это; Я, вероятно, много задаю здесь, но я новичок в PHP, и я действительно ищу идиоматический/элегантный способ сделать это. Каковы ваши лучшие практики?
Добавление (подробнее об этом классе)
Весьма вероятно, что этот класс пытается сделать слишком много, но это порт старой библиотеки Perl для создания и обработки форм. Вероятно, есть способ деления параметров конфигурации, чтобы воспользоваться наследованием и полиморфизмом, но он может быть фактически контрпродуктивным.
По запросу здесь представлен частичный список некоторых параметров (код Perl). Вы должны увидеть, что они не очень хорошо сопоставляются с подклассами.
У класса, конечно же, есть геттеры и сеттеры для многих из этих свойств, поэтому пользователь может их преодолеть; цель этого сообщения (и то, что делает оригинальный код) - обеспечить компактный способ создания экземпляров этих объектов с уже заданными параметрами. Это действительно делает очень читаемый код.
# Form Behaviour Parameters
# --------------------------
$self->{id}; # the id and the name of the <form> tag
$self->{name} = "webform"; # legacy - replaced by {id}
$self->{user_id} = $global->{user_id}; # used to make sure that all links have the user id encoded in them. Usually this gets returned as the {'i'} user input parameter
$self->{no_form}; # if set, the <form> tag will be omitted
$self->{readonly}; # if set, the entire form will be read-only
$self->{autosave} = ''; # when set to true, un-focusing a field causes the field data to be saved immediately
$self->{scrubbed}; # if set to "true" or non-null, places a "changed" radio button on far right of row-per-record forms that indicates that a record has been edited. Used to allow users to edit multiple records at the same time and save the results all at once. Very cool.
$self->{add_rowid}; # if set, each row in a form will have a hidden "rowid" input field with the row_id of that record (used primarily for scrubbable records). If the 'scrubbed' parameter is set, this parameter is also automatically set. Note that for this to work, the SELECT statement must pull out a unique row id.
$self->{row_id_prefix} = "row_"; # each row gets a unique id of the form id="row_##" where ## corresponds to the record rowid. In the case of multiple forms, if we need to identify a specific row, we can change the "row_" prefix to something unique. By default it "row_"
$self->{validate_form}; # parses user_input and validates required fields and the like on a form
$self->{target}; # adds a target window to the form tag if specified
$self->{focus_on_field}; # if supplied, this will add a <script> tag at the end of the form that will set the focus on the named field once the form loads.
$self->{on_submit}; # adds the onSubmit event handler to the form tag if supplied
$self->{ctrl_s_button_name}; # if supplied with the name of the savebutton, this will add an onKeypress handler to process CTRL-S as a way of saving the form
# Form Paging Parameters
# ----------------------
$self->{max_rows_per_page}; # when displaying a complete form using printForm() method, determines the number of rows shown on screen at a time. If this is blank or undef, then all rows in the query are shown and no header/footer is produced.
$self->{max_pages_in_nav} = 7; # when displaying the navbar above and below list forms, determines how many page links are shown. Should be an odd number
$self->{current_offset}; # the current page that we're displaying
$self->{total_records}; # the number of records returned by the query
$self->{hide_max_rows_selector} = ""; # hide the <select> tag allowing users to choose the max_rows_per_page
$self->{force_selected_row} = ""; # if this is set, calls to showPage() will also clear the rowid hidden field on the form, forcing the first record to be displayed if none were selected
$self->{paging_style} = "normal"; # Options: "compact"
Мы можем, конечно, позволить себе втягиваться в более длительные дебаты вокруг стиля программирования. Но я надеюсь избежать этого, за разумность всех участников! Здесь (код Perl, снова) является примером создания экземпляра этого объекта с довольно внушительным набором параметров.
my $form = new Valz::Webform (
id => "dbForm",
form_name => "user_mailbox_recip_list_students",
user_input => \%params,
user_id => $params{i},
no_form => "no_form",
selectable => "checkbox",
selectable_row_prefix => "student",
selected_row => join (",", getRecipientIDsByType('student')),
this_page => $params{c},
paging_style => "compact",
hide_max_rows_selector => 'true',
max_pages_in_nav => 5
);