Хорошо, я знаю, что название этого вопроса почти идентично тому, когда я должен использовать программирование на основе событий? но ответы на этот вопрос не помогли мне решить, следует ли мне использовать события в конкретном случае, с которым я сталкиваюсь.
Я разрабатываю небольшое приложение. Это простое приложение, и по большей части его функциональность является базовой CRUD.
При определенных событиях (при изменении определенных данных) приложение должно записать локальную копию указанных данных в файл. Я не уверен, что это лучший способ реализовать это. Я могу:
- Запускайте события, когда данные модифицируются, и привязывайте ответ (генерируйте файл) к таким событиям. В качестве альтернативы, реализуйте шаблон наблюдателя. Это кажется ненужной сложностью.
- Вызывайте код, генерирующий файл, непосредственно из кода, который модифицирует данные. Гораздо проще, но кажется неправильным, что зависимость должна быть такой, то есть неправильно, что основная функциональность приложения (код, который изменяет данные) должна быть связана с этим дополнительным перком (кодом, который генерирует файл резервной копии). Я знаю, однако, что это приложение не будет развиваться до такой степени, что эта связь создает проблему.
Каков наилучший подход в этом случае?
Ответы:
Следуйте принципу KISS: будь проще, глупее или принципу YAGNI: он тебе не понадобится.
Вы можете написать код как:
Или вы можете написать код как:
При отсутствии веской причины поступить иначе, следуйте более простому маршруту. Такие методы, как обработка событий, являются мощными, но они увеличивают сложность вашего кода. Для работы требуется больше кода, и это усложняет отслеживание того, что происходит в вашем коде.
События очень важны в правильной ситуации (представьте, что вы пытаетесь программировать пользовательский интерфейс без событий!) Но не используйте их, когда вместо этого вы можете использовать KISS или YAGNI.
источник
Пример, который вы описываете для простых данных, где модификация вызывает некоторый эффект, может быть прекрасно реализован с помощью шаблона проектирования наблюдателя :
Подход, основанный на событиях, стоит вложений в более сложные сценарии, когда может происходить много разных взаимодействий, в контексте «многие ко многим», или если предусмотрены цепные реакции (например, субъект информирует наблюдателя, который в некоторых случаях хочет изменить предмет или другие предметы)
источник
Как вы говорите, события - отличный инструмент для уменьшения связи между классами; поэтому, хотя это может потребовать написания дополнительного кода на некоторых языках без встроенной поддержки событий, оно уменьшает сложность общей картины.
События, возможно, являются одним из наиболее важных инструментов в ОО (согласно Алану Кейу - объекты связываются, отправляя и получая сообщения ). Если вы используете язык, который имеет встроенную поддержку для событий, или рассматриваете функции как первоклассных граждан, то использовать их не составит труда.
Даже в языках без встроенной поддержки количество шаблонов для чего-то вроде шаблона Observer довольно минимально. Вы можете найти где-нибудь приличную универсальную библиотеку событий, которую вы можете использовать во всех своих приложениях, чтобы минимизировать шаблон. (Универсальный агрегатор событий или медиатор событий полезен практически в любом приложении).
Стоит ли в маленьком приложении? Я бы сказал определенно да .
Если вы думаете: «О, но на самом деле это очень маленькое приложение, это не имеет большого значения» , подумайте:
В целом, размер приложения не должен быть решающим фактором для того, чтобы сохранить классы слабо связанными; Принципы SOLID предназначены не только для больших приложений, они применимы к программному обеспечению и кодовым базам любого масштаба.
Фактически, время, сэкономленное на модульном тестировании ваших слабо связанных классов, должно уравновешивать любое дополнительное время, затрачиваемое на разделение этих классов.
источник
Шаблон наблюдателя может быть реализован гораздо меньшим образом, чем его описывает статья в Википедии (или книга GOF), при условии, что ваши языки программирования поддерживают что-то вроде «обратных вызовов» или «делегатов». Просто передайте метод обратного вызова в ваш код CRUD (метод наблюдателя, который может быть либо универсальным методом «записи в файл», либо пустым). Вместо «запуска события» просто вызовите этот обратный вызов.
Результирующий код будет лишь минимально более сложным, чем прямой вызов кода, генерирующего файлы, но без недостатков, связанных с жесткой связью несвязанных компонентов.
Это принесет вам «лучшее из обоих миров», не жертвуя развязкой для «ЯГНИ».
источник