четверг, 9 января 2014 г.

О пользе выбора

Мы очень часто сталкиваемся с дилеммой при разработке проекта или одной из его фич: что выбрать, подход А или подход Б? Что лучше, использовать WCF или веб-сервисы; Entity Framework или NHibernate; читать конфигурацию из файла конфигурации или из базы данных?

Очевидно, что если я отстаиваю подход А, то именно он является верным, и мне лишь осталось убедить собеседника в этом. С другой стороны, очень часто мне может лишь казаться, что мой подход лучше согласно текущего понимания проблемы, а мой оппонент может рассматривать эту же проблему с иной точки зрения.

Поскольку иногда бывает сложным убедить собеседника в своей правоте мы можем прийти к заключению, что нужно найти компромиссное решение. Здесь мы ступаем на очень тонкий лед. Может показаться, что лучшим решением этой дилеммы будет создание гибкого решения, которое будет удовлетворять обоим подходам одновременно. Очевидно, что в этом случае мы не просто сможем переключаться от одного решения к другому: мы поддерживаем два решения сразу! Разве не прекрасно?

Нет, не прекрасно! Да, хороший дизайн должен обеспечивать свободу маневра в будущем, когда неизвестные факторы, ограничения или новые потребности пользователя начинают проявлять себя во всей красе. Но при этом хороший дизайн не обязан удовлетворять всем текущим потенциальным факторам одновременно.

В этом плане дизайн должен быть подобен глине, которую мы в состоянии изменить при изменении требований или нашего понимания системы. Вопрос, который мы должны задать себе такой: как сделать дизайн таким, чтобы мы могли безболезненно перейти от одного решения к другому? Как сделать не принципиальным, какой из предложенных подходов использовать?

А чем это отличается от исходного варианта, когда наша система удовлетворяла обоим критериям?

Ответ простой: в первом случае, мы дизайним нашу систему, отталкиваясь от двух доступных вариантов решения: правильного варианта А, который отстаиваю я, и неправильного варианта Б, который отстаивает мой коллега. Но проблема в том, что никто не может быть уверенным в том, что этот набор решений полон. А вдруг к нашему обсуждению подключится еще двое коллег, в результате чего появится еще как минимум два других варианта решения этой же проблемы!

Альтернативный же подход подразумевает, что независимо от принятого сейчас решения, мы сделаем все возможное, чтобы могли спокойно перейти от него к другому решению, решению, о котором мы с вами еще не знаем!

Основная суть дизайна сводится к тому, чтобы спрятать некоторую информацию внутрь модуля и оперировать с ним на более высоком уровне абстракции, не думая о том, как он реализован внутри. При этом, опять же, речь не о том, что данный класс реализует интерфейс и мы сможем подменить ее во время исполнения, а в том, что наш класс или модуль прячет с глаз долой некоторую логику, что позволит изменить ее реализацию не трогая всех существующих клиентов.

Поэтому когда в следующий раз вы столкнетесь с такой ситуацией, когда у вас будет два или более возможных решения проблемы, думайте не о том, какое из решений лучше, а о том, как сделать так, чтобы ваше мнение можно было легко изменить в будущем, не «ломая» существующих клиентов. Да, да, все верно, речь о той самой инкапсуляции, но на более высоком уровне абстракции: речь об инкапсуляции своих собственных решений, об инкапсуляции, которая позволит вам ошибаться, а также позволит реагировать на изменения требований, которые обязательно будут происходить в любом реальном проекте.

Именно в этом и заключается роль проектировщика: ответить на вопрос «А что будет, если …». При этом, чем сильнее чувство неуверенности по конкретному модулю, тем сильнее его реализация должна быть изолирована от всего остального мира.

В некотором смысле мы можем рассматривать модульность системы, как зоны нашей «неуверенности»: если в одной из них начнется пожар из-за изменения требований, то огонь изменений должен ограничиться лишь одним модулем, или, по крайней мере, минимальным их количеством.

Ссылки по теме

З.Ы. Данная заметка навеяна выступлением Келвина Хенни “The Architecture of Uncertainty”

Комментариев нет:

Отправить комментарий