Должен ли объект всегда инкапсулировать данные, над которыми работают его методы?

Я разрабатываю класс 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();

С точки зрения как непосредственного дизайна, так и будущего расширения, один шаблон дизайна имеет больше смысла, чем другой? Или есть третий, возможно, лучший шаблон дизайна, который я должен использовать?

2

Решение

Я предпочитаю вариант № 1. Это чище и проще в использовании IMO, а вариант № 2 не дает никаких преимуществ или функциональности по сравнению с первым.

Думая об этом на более высоком уровне, инкапсуляция используется, чтобы скрыть данные и детали реализации, использованные для выполнения задачи, определенной в классе. В варианте № 2 вы на самом деле не скрываете детали реализации, вы, по сути, просите класс сохранить для вас что-то ненужное под видом «инкапсуляции».

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

1

Другие решения

С моей точки зрения,
если вы используете интерфейсный класс, вы можете определить атрибуты и функции в интерфейсе. Потому что интерфейс может быть реализован из более чем одного класса.
Если это так, способ 1 должен быть более удобным для этого.

Если вы можете использовать только класс и не реализовывать его из другого интерфейса, было бы лучше, если бы вы использовали метод 2.

0

По вопросам рекламы [email protected]