Я читаю книгу «Изучение шрифтов» Ремо Янсена. В одном разделе автор описывает, как создать очень простую платформу MVC для проверки концепции, включая создание Model
класса, и говорит следующее:
Для модели необходимо указать URL-адрес веб-службы, которую она использует. Мы собираемся использовать декоратор класса с именем ModelSettings, чтобы установить URL-адрес службы, которая будет использоваться. Мы могли бы внедрить URL службы через ее конструктор, но считается плохой практикой вводить данные (в отличие от поведения) через конструктор класса .
Я не понимаю это последнее предложение. В частности, я не понимаю, что значит «вводить данные». Мне кажется, что почти во всех введениях в классы JavaScript с использованием упрощенных примеров данные вводятся («вводятся»?) В конструктор через его параметры. Например:
class Person {
constructor(name) {
this.name = name;
}
}
Я, конечно, считаю name
данные, а не поведение, и они повсеместно включены в этот пример в качестве параметра конструктора, и никогда не упоминается, что это плохая практика. Таким образом, я предполагаю, что неправильно понимаю что-то в приведенной выше цитате, что означает «данные» или «вводить», или что-то еще.
Ваши ответы могут включать объяснения того, когда, где, как и зачем использовать декораторы в JavaScript / TypeScript, так как я сильно подозреваю, что концепция тесно связана с пониманием, которое я ищу. Однако, что еще более важно, я хочу понять в целом, что подразумевается под внедрением данных через конструктор классов и почему это плохо.
Чтобы дать больший контекст вышеприведенной цитате, вот такая ситуация: Model
создан класс, который в этом примере будет использоваться для создания моделей фондовых бирж, одна для NASDAQ и одна для NYSE. Для каждой модели требуется путь к веб-службе или файлу статических данных, который будет предоставлять необработанные данные. В книге говорится, что для этой информации должен использоваться декоратор, а не параметр конструктора, что приводит к следующему:
@ModelSettings("./data/nasdaq.json")
class NasdaqModel extends Model implements IModel {
constructor(metiator : IMediator) {
super(metiator);
}
...
}
Я просто не понимаю, почему я должен добавить URL службы через декоратор, а не просто как параметр для конструктора, например
constructor(metiator : IMediator, serviceUrl : string) {...
источник
Ответы:
Я дам автору пользу от сомнений, и, возможно, именно так обстоят дела с Typescript, но в других случаях это абсолютно необоснованное утверждение, которое не следует воспринимать всерьез.
Вдобавок ко всему, я могу подумать о множестве ситуаций, когда передача данных через конструктор хороша, некоторые - нейтральны, но ни одна, где это плохо.
Если конкретный класс зависит от определенного фрагмента данных для того, чтобы быть в допустимом состоянии и работать правильно, имеет смысл требовать эти данные в конструкторе. Класс, представляющий последовательный порт, может принимать имя порта, файловый объект может требовать имя файла, холст для рисования, требующий его разрешения, и т. Д. Если вы не передадите данные в конструктор, возможно, вы можете получить объект в недопустимом состоянии, что нужно следить и проверять. В противном случае вы можете проверить только при создании объекта и впоследствии предположить, что он работает по большей части. Заявление авторов делает эту выгодную ситуацию невозможной.
Кроме того, принятие решения о запрете передачи данных в конструкторе также делает невозможным практически все неизменяемые объекты. Неизменяемые объекты имеют множество преимуществ во многих ситуациях, и все они будут исключены с политикой автора.
Даже если изменяемые объекты - это то, что вы хотите, как это плохая практика:
в пользу:
Неужели автор действительно думает, что первое - это плохая практика, и мне всегда следует выбирать вариант 2? Я думаю, что это сумасшедший разговор.
Итак, поскольку у меня нет этой книги, и я бы ее не прочитал, даже если бы у меня ее было, я бы посмотрел на это заявление и почти любое общее утверждение в этой точке со значительным подозрением.
источник
Я думаю, что это зависит от контекста, какая модель обсуждается здесь. У меня нет книги Ремо, но я предполагаю, что эта модель является своего рода сервисной моделью, которая должна извлекать данные из удаленного веб-сервиса. В этом случае, будучи моделью веб-службы, лучше передать все необходимые данные в качестве аргументов в методах веб-службы, что делает службу без сохранения состояния.
Служба без сохранения состояния имеет несколько преимуществ, например, любому, кто читает вызов метода службы, не нужно искать, когда служба построена, чтобы узнать подробности вызываемой службы. Все детали показаны в аргументах, используемых в вызове метода (кроме удаленного URL).
источник
Просто угадай.
Если бы я услышал «вводить поведение, а не данные», я бы подумал, вместо того, чтобы делать это:
(Извините за пример в псевдокоде):
Сделать это:
Таким образом, вы всегда можете изменить поведение шума, сделать его случайным, зависящим от одной внутренней переменной ...
Я думаю, что это все о правиле «составной состав вместо наследования». Это большое правило, я должен сказать.
Это НЕ ОЗНАЧАЕТ, что вы не можете «внедрить» имя в объект «Персона», очевидно, потому что это имя является чисто бизнес-данными. Но в приведенном вами примере, веб-сервисе, URL-адрес - это то, что вам нужно, чтобы сгенерировать что- то , связывающее сервис. Это как-то поведение: если вы вводите URL, вы вводите «данные», необходимые для построения «поведения», поэтому в этом случае лучше сделать поведение снаружи и внедрить его готовым к использованию: вместо этого введите URL-инъекцию полезное соединение или полезное построение соединений.
источник