суббота, 21 августа 2010 г.

11/97: Кодируйте на языке предметной области

Это перевод Code in the Language of the Domain. Автор: Dan North.

Из "97-ми вещей, которые должен знать каждый программист".

Представьте себе два исходных кода. В первом вы видите что-то подобное:
if (portfolioIdsByTraderId.get(trader.getId())
  .containsKey(portfolio.getId())) {...}
Вы чешете затылок, пытаясь догадаться, что может делать этот код. Выглядит как взятие ID из объекта trader и использование его для получения другого ID, после чего – поиск еще одного ID из объекта portfolio... Почесывание затылка почему-то не помогает. Вы ищете определение portfolioIdsByTraderId и находите следующее:
Map<int, Map<int, int>> portfolioIdsByTraderId;
Постепенно вы выясняете, что этот код делает что-то похожее на выяснение того, имеет ли трейдер доступ к портфелю акций. И конечно же, этот (или похожий на него) фрагмент кода будет повторяться везде, где будет требоваться выяснить, есть ли у трейдера доступ к портфелю.

А в другом исходном коде вы находите вот такую строчку:
if (trader.canView(portfolio)) {...}
И никакого почесывания затылка не требуется. Вам не нужно знать подробности, что у этой функции внутри. Вероятнее всего, там будет подобное приведенному выше фрагменту, но это уже дело trader, а не ваше.

А теперь скажите, с каким кодом вы бы предпочли работать?

Когда-то давно были только простые структуры данных: биты, байты и символы (на самом деле те же байты, но нам больше нравилось считать их буквами, цифрами и знаками). С числами было уже чуть сложнее – наша десятичная система не очень хорошо «ложилась» на двоичную, и поэтому было несколько различных типов с плавающей запятой. Потом появились массивы и строки (на самом деле - такие же массивы). Потом – стеки, очереди, хеши, связанные списки и другие замечательные структуры, не существующие в реальном мире. И «компьютерные науки» тратили кучу усилий на то, чтобы поставить в соответствие объектам из реального мира эти достаточно ограниченные структуры данных. Настоящие же гуру могли даже запомнить то, как именно они это сделали.

Потом появились типы, определенные пользователем! Это серьезно изменило правила игры. Если в вашей области есть сущности «трейдер» и «портфель», то вы можете смоделировать их при помощи типов данных с именами Trader и Portfolio. Но еще более важно то, что вы можете моделировать отношения между ними, тоже используя термины из предметной области.

Если вы программируете, не используя термины предметной области, то тем самым вы создаете тайное знание о том, что например вот этот int означает идентификатор трейдера, а вот тот – идентификатор портфеля (и лучше их не путать!). А если вы представляете какую-либо концепцию («Некоторые трейдеры не могут просматривать отдельные портфели - это не законно») при помощи алгоритма, подобного поиску соответствия в таблице идентификаторов, то вы не даете тем, кому придется с этим разбираться, вообще никакой подсказки.

Программист, пришедший за вами, не будет иметь того тайного знания, которое имели вы. Так зачем делать его тайным? Использовать ключ для поиска другого ключа, используемого для проверки наличия соответствия – не самый распространенный прием. Каким образом кто-то должен догадаться о том, какое именно правило из предметной области тут скрыто?

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

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

4 комментария:

  1. Интересная статья, спасибо! Не задумывался над этим раньше.

    ОтветитьУдалить
  2. Пардон, в данном случае лучше перевести как "трейдер" (специалист по биржевой торговле) и "портфель" (набор акций, купленный этим самым трейдером).

    ОтветитьУдалить
  3. Подправил, спасибо.

    У меня в блоге ещё комбинация Ctrl + Enter работает (напоминалка в правом-верхнем углу должна быть). Это на будущее :)

    ОтветитьУдалить

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.