Pull to refresh

Об использовании паттернов

Reading time 3 min
Views 5.6K
К сожалению, иногда приходится наблюдать случаи, когда люди, прошедшие паттерны проектирования в институте в рамках курса программирования, или же прочитавшие книжку с паттернами сразу после учебника по программированию, начинают применять их в работе буквально с первого класса. Иногда это даёт результат, чаще всего с паттернами Singleton (хотя бы знают про double locking idiom). Но чаще всего возникает ситуация, когда человек применяет паттерн просто для того, что его применить. И это плохо.

Для начала, что такое паттерн? Можно перевести как «образец», «пример», «модель», но мне больше всего нравится слово «шаблон» или же «шаблон проектирования». Потому что любой паттерн это не образец, с которого надо копировать ваш код. Это образец оформления кода, которому надо следовать. Разница такая же, как между образцом документа, который висит на стене, и шаблоном документа в MS Word / OpenOffice Writer, который используется для единообразного оформления (отступы, шрифты, оформление абзацев).

Немного из собственного опыта. Стаж программирования 13 лет. Через два года самостоятельного обучения по книжкам (ни одного слова о паттернах) написал несколько приложений «под заказ», одно из которых используется до сих пор. Но только спустя ещё два года задумался о том, что:
  • Во-первых, код должен быть читаемым хотя бы для самого себя
  • Во-вторых, с кодом, вполне возможно, придётся работать кому-то другому
И тогда я начал задаваться вопросами, вроде:
  • Как обозвать коллекцию почтовых адресов? MailAccounts?
  • Куда положить методы, которые отвечают за работу с почтовыми адресами?
  • Куда сложить методы, которые работают с базой данных, чтобы потом легко их было найти?
  • Как лучше организовать доступ к объекту, который в системе должен быть один и только один? Сделать public static final (const) поле? Сделать public static метод?
Много позже стал понимать, что ответ на эти вопросы как раз и дают паттерны. Шаблоны проектирования не просто диктуют правила именования (тогда они мало чем отличаются от правил оформления кода), но и определяют структуру кода.А определяют ли они способ решения задачи? Нет, выбор способа решения конкретной задачи бизнес-задачи всё равно остаётся за программистом. Например, нам нужно организовать доступ к объектам в базе. Это можно сделать двумя способами:
  • сделать простой доступ к базе с использованием методов getName(int id), setName(int id)
  • выделить под каждую строку в базе данных свой экземпляр объекта
Или, нам нужно сделать парсер формата CSV. Мы можем:
  • Сделать «тупой» парсер на основе нескольких методов parseLine, parseToken, parseString(), работая с последовательностями символов
  • Сделать парсер, который бы работал с отдельными символами (onSemicolon(), onDot(), onQuote(), etc)
Для решения бизнес-задачи мы можем выбрать один из нескольких вариантов решения задачи. Ошибка начинающего программиста, знакомого с шаблонами проектирования, в том, что вместо перебора способов решения задачи он начинает перебирать известные (и неизвестные) ему шаблоны проектирования с целью выбрать подходящий шаблон. И, часто бывает, ошибается. В случае с объектами в базе данных под известный шаблон попадает второй способ, с отдельными экземплярами объекта для каждой строки в базе данных. Но программисту даже в голову не придёт, что большая часть работы может идти с помощью bulk-операций, и тогда нужно использовать другой паттерн. В случае с парсером программист выбирает работу с отдельными символами, так как это хорошо ложится на известный ему паттерн state machine. Но в результате он получает код, который очень сложно читать и невозможно дорабатывать. Потому что свой выбор он начал с выбора шаблона проектирования, а не с выбора способа решения задачи.

Даже если рассматривать более высокоуровневые шаблоны, вроде Model-View-Controller, их применение не должно быть ответом на поставленную бизнес-задачу. Программист должен чётко осознавать, что в его случае действительно нужно иметь возможность отделить поведение системы от отображения. И, придя к этой идее, представив, как он это будет делать хотя бы примерно, обратить внимание на шаблон MVC, который пояснит ему, какие именно части как написать, как их назвать, и какими функциями наделить.

Знание шаблонов проектирования помогают написать код. В случае простых шаблонов они помогают оформить код, чтобы он был более понятным другим людям. Более сложные шаблоны помогают структурировать код. Но обязательна должна быть цепочка «задача» — «способ решения» — «шаблон» — «код», а не «задача» — «шаблон» — «код».

Update: Переписал топик, акцентировав на том, где кончается решение задачи и начинается паттерн. Не уверен, стоит ли переопубликовывать топик или же надо делать новый. Просьба сильно не бить за незнание паттернов поведения на Хабре
Tags:
Hubs:
+7
Comments 24
Comments Comments 24

Articles