Я разрабатываю класс PHP, RequestSanitize
, это обработает некоторый необработанный пользовательский ввод. Один способ, которым я мог сделать это:
class DataSanitizer implements DataSanitizerInterface {
protected $_schema;
public function __construct($schema){
$this->_schema = $schema;
// Blah blah blah
}
public function sanitize($data) {
$sanitizedData = [];
// Blah blah blah populate $sanitizedData
...
return $sanitizedData;
}
}
Таким образом, в основном класс служит для обслуживания схемы всякий раз, когда sanitize
называется. Таким образом, он привык бы так:
$ds = new DataSanitizer("/path/to/schema");
$sanitizedData = $ds->sanitize($_GET);
В этом случае, я мог бы даже сделать sanitize
статический член.
Другой вариант будет:
class DataSanitizer implements DataSanitizerInterface {
protected $_schema;
protected $_sanitizedData = [];
public function __construct($schema){
$this->_schema = $schema;
// Blah blah blah
}
public function sanitize($data) {
// Blah blah blah
$this->_sanitizedData = ...
return $this;
}
public function data(){
return $this->_sanitizedData;
}
}
Который привык бы так:
$ds = new DataSanitizer("/path/to/schema");
$ds->sanitize($_GET);
$sanitizedData = $ds->data();
С точки зрения как непосредственного дизайна, так и будущего расширения, один шаблон дизайна имеет больше смысла, чем другой? Или есть третий, возможно, лучший шаблон дизайна, который я должен использовать?
Я предпочитаю вариант № 1. Это чище и проще в использовании IMO, а вариант № 2 не дает никаких преимуществ или функциональности по сравнению с первым.
Думая об этом на более высоком уровне, инкапсуляция используется, чтобы скрыть данные и детали реализации, использованные для выполнения задачи, определенной в классе. В варианте № 2 вы на самом деле не скрываете детали реализации, вы, по сути, просите класс сохранить для вас что-то ненужное под видом «инкапсуляции».
Если бы вы работали в многопоточной среде, опция # 1 также позволила бы упростить повторное использование вашего объекта в потоках. Это делает много предположений о повторяющейся природе того, что вы используете для санитарии, но № 2, по сути, оставляет вам создание объектов санитарии для каждого потока, опять же, для хранения данных, которые не нужны или являются ядром для функции класса.
С моей точки зрения,
если вы используете интерфейсный класс, вы можете определить атрибуты и функции в интерфейсе. Потому что интерфейс может быть реализован из более чем одного класса.
Если это так, способ 1 должен быть более удобным для этого.
Если вы можете использовать только класс и не реализовывать его из другого интерфейса, было бы лучше, если бы вы использовали метод 2.