Предупреждение: Данный пост пропах субъективной оценкой и холиварными суждениями.

Давайте поговорим про именование классов!

Делая код-ревью или просматривая чужой код я часто натыкаюсь на всевозможные классы с именами типа Parser, Decoder, Encoder.

Еще хлеще, когда в таком коде множество статических методов.

Как Вы думаете, насколько это валидно?

Лично у меня всегда возникает вопрос - “Почему колесо не называется катало?”

Хочется подискутировать на этот момент.

Вот проектируете вы новый супер-сервис, который парсит входящее откуда-то сообщение, расшифровывает его и складывает в БД, например.

Так, ну тут у нас будет определенно какой-то хендлер, куда сообщение это валится, из которого мы сначала прогоним это сообщение через Decoder, а затем Parser и остаток сложим в БД.

Логично? Ну все, пишем код.

Но не все так просто, как кажется.

Может измениться тип шифрования? Может. Сегодня тебе присылают сообщение в base64, завтра с битовым сдвигом и контрольной суммой.

И что будем делать в таком случае? Писать еще один метод в классе Decoder. Или создадим новый класс, например NewDecoder.

Может измениться структура сообщения? Может. Сегодня тебе шлют XML, завтра Yaml. Что делаем? Конечно же YamlParser.

А еще бывало такое, ну признайтесь себе, когда в какой-нибудь Parser было желание засунуть еще и валидатор и математику какую-нибудь. Бывало ведь?)

В итоге такой класс начинает и парсить, и валидировать, и за кофеём бегать и штаны гладить.

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

Так как же быть? Связывайте классы с реальными вещами и называйте классы тем, чем они являются. Parser - не очень реальная сущность, а что-то абстрактное, что умеет парсить сообщение. А сообщение - это конкретный объект.

Валится вам на вход какое-то сообщение - назовите класс Message, задекларируйте методы - decode_base64/encode_base64/parse_to_dict.

Если сообщение XML - сделайте класс XmlMessage, в котором отнаследуетесь от Message и перезагрузите нужные методы. Может и нового добавите.

Если Yaml - YamlMessage.

“Но ведь ничего не изменилось? Мы также плодим кучу классов и сколько хотим методов - столько и пишем!”.

Еще как изменилось. Давайте приведу пример с классом Parser:

decoded_message = Decoder(msg).decode_message()

parsed_message = Parser(msg).parse_xml()

save_to_db(parsed_message)

А теперь приведу пример с классом Message:

message = XmlMessage(msg)

message.decode()

message.parse()

message.save_to_db()

Какие различия мы видим?

Во первых это интуитивно-понятное взаимодействие с классом.

Во вторых мы инкапсулируем логику - нам не нужно знать что парсить и как парсить.

А в третьих, это еще и красивей выглядит :)

То есть мы говорим “Колесо - катись. Колесо - остановись.”, вместо “О силы трения качения, используя свою великую мощь - дайте мне катящееся колесо”.

Давайте подискутируем про это.

Может я в корне не прав и надо плодить парсеры с декодерами, а колесо называть каталом?