Чистая архитектура (логический дизайн) и чистый код (физический дизайн) имеют общий ключ к успеху, а именно разделение задач/ответственности и сохранение их независимости. Если с этой точки зрения логическая схема не является чистой, за ней последует физический план.

Единая ответственность

Давайте подумаем: техническое задание (или Спецификация работы, или Требования к работе): Заказчик утверждает: Как пользователь, я могу отмечать различные документы.

Агент

В системе, которую увидит пользователь, он ставит теги, тогда как на самом деле за него работает класс/модуль. И это мы называем «Агент», который несет ответственность за то, чтобы это произошло. В этом случае мы называем этого агента «Tagger», который реализует концепцию «Tagged» с объектом, называемым «Tag», на объектах, которые называются «Tagable».

Смерть логического дизайна

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

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

Действие к агенту существительному

Глагол к его существительному к интерфейсу

Определить глагол из требований и преобразовать его в понятие с герундием (ing) не так уж сложно.

Я хочу пометить/Возможность пометить — — → Пометка → Интерфейс

Tagging { doTag(Tag t, Taggable object);}

Я хочу назначать типы/Возможность назначать типы — — → Классификация

Classifying { doClassify(Type t, Classifiable object);}

Я хочу создать версию/Возможность создавать версии — — → Управление версиями

Versioning { doVersion(Version t, Versionable object);}

Агент Существительное (суффикс - или, эээ)

Теперь тот, кто реализует эту концепцию Действия, становится Агентом (Исполнителем).

Тегирование — — —› Тегирование — —› Реализация

Tagger Implements Tagging { 
   doTag(Tag t, Taggable object){
          ##TODO: any business logic e.g. check if tag exists 
          object.tag(t);
    }
  }

Концепция действия/Интерфейс в сравнении с чертами объекта/Интерфейс (тегирование и тегирование)

Чтобы агент выполнил действие над объектом, объект должен быть совместим с этим действием. Эта совместимость объекта является его способностью/чертой/интерфейсом для взаимодействия с агентом.

Taggable { tag(Tag t);}

И когда объект реализует это

Object implements Taggable { 
      tag(Tag t){
            this.setTagId(t.getId()); // any other business logics.
         }
}

Возможность повторного использования и изменения требований

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

Мышление/Концепция всегда на первом месте

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

###

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