Prefixed Naming

The following text is a partial translation of the original English article, performed by ChatGPT (gpt-3.5-turbo) and this Jekyll plugin:

Если вы впервые посмотрите на исходный код Takes или Cactoos, скорее всего, как и многие другие, вас сразу же заинтересует соглашение об именовании, которое подразумевает, что большинство имен классов имеют двухбуквенные префиксы: BkSafe, RqFake, RsWithStatus, TkGzip и так далее. Если быть честным, я не видел ни одного разработчика на Java, который был бы комфортен с этим соглашением с первого взгляда. Однако я видел множество тех, кто полюбил его с течением времени. Эта статья предназначена для тех, кто хочет перейти из первой категории во вторую.

Любой программный пакет, модуль, библиотека или фреймворк достаточного размера содержит большое количество классов. Так и должно быть. Если этого нет, то определенно есть проблема с его дизайном. Возникает вопрос, как назвать эти классы. Самый простой и очевидный подход - использовать в Java и ее флагманском фреймворке Spring длинные и описательные имена классов. Вот несколько примеров:

  • “SimpleBeanFactoryAwareAspectInstanceFactory” - “SimpleBeanFactoryAwareAspectInstanceFactory”

  • TransactionAwarePersistenceManagerFactoryProxy” - “TransactionAwarePersistenceManagerFactoryProxy

  • AbstractAnnotationConfigDispatcherServletInitializer” - “AbstractAnnotationConfigDispatcherServletInitializer

Это мусор, не так ли?

Гораздо более сложный и затратный способ названия классов - это парадигма DDD, которая предлагает использовать существительные после сущностей в реальном мире, такие как порт, машина, книга, история, пользователь, сокет и так далее. Выявление правильных сущностей является большим вызовом для архитектора программного обеспечения. Плохой архитектор просто прибегнет к ConnectionFactoryUtils или DefaultListableBeanFactory и назовет его днем. Более профессиональный архитектор может потратить часы или дни, но в конечном итоге придумает что-то более ориентированное на домен.

Допустим, вы относитесь к последнему случаю и вам удалось найти правильные существительные. Сколько из них будет в вашей предметной области? Я думаю, что несколько десятков. Даже если приложение достаточно сложное, у вас не будет более 30 сущностей в его предметной области. Однако, как уже упоминалось выше, количество классов будет намного больше, иногда более тысячи или даже больше. Таким образом, второй проблемой, с которой вы столкнетесь, будет то, как назвать классы, которые являются “сущностями с определителями”. Например, у вас есть порт, а также случайный порт и порт TCP, а также закрытый порт и порт, который еще не открыт и так далее.

Будут существительные с прилагательными: случайный порт, закрытый порт, открытый порт, порт TCP, сломанный порт и так далее. Как назвать эти классы? Может быть, так просто: RandomPort, OpenedPort, ClosedPort, TcpPort. Может быть, но я считаю, что лучше превратить общую часть Port в общий префикс Pt для всех классов:

  • PtOpened

  • PtClosed

  • PtTcp

Единственным недостатком такого подхода является то, что новичкам может быть непонятен префикс Pt. Действительно, на его изучение может потребоваться некоторое время (несколько минут). Однако преимущества значительно превышают этот недостаток: как только вы изучите все префиксы, используемые в приложении (их будет всего несколько, так как количество сущностей в данной области довольно ограничено), вы сразу поймете, к какой части иерархии типов принадлежит класс (этот, например, из Takes):

Request <– RqChunk Request <– RqGreedy Request <– RqMultipart Back <– BkParallel Back <– BkSafe Take <– TkFailure Take <– TkGzip Take <– TkMeasured

Как только вы видите префикс Rq, вы сразу понимаете, что имеете дело с реализацией интерфейса org.takes.Request. Не с ServletRequest из JDK, не с HttpRequest из Spring и не с Request из OkHttp. Вы знаете, что это Request из Takes!

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

Translated by ChatGPT gpt-3.5-turbo/42 on 2023-11-18 at 05:06

sixnines availability badge   GitHub stars