С каким сложностями сталкивался при разработке чата

Ответ

Ответ не найден

Ответ 18+ 🔞

Слушай, вот сидишь ты такой, пишешь на Python, думаешь — ну всё, я ж бог ООП, щас накодирую архитектуру, от которой все ахнут. А потом, блядь, через полгода смотришь на свой же код и думаешь: «Что за хуйню я тут написал? Это ж пиздец, а не код».

Вот, например, берёшь ты класс User. Ну, казалось бы, что может быть проще? Пользователь, имя, почта, всё дела. А потом начинается: «А давайте добавим скидку для премиум-пользователей! А давайте ещё логин через соцсети! А давайте ещё историю заказов!» И твой красивый класс превращается в этого монстра:

class User:
    def __init__(self, username, email, password, social_login_token=None, premium_status=False, discount_rate=0, order_history=[], last_login_ip=None, avatar_url=None, is_verified=False, two_factor_enabled=False, ...):
        self.username = username
        self.email = email
        self.password = password  # Который, ясное дело, хранится в открытом виде, потому что кому охота с хешами возиться?
        # ... и ещё 40 полей, блядь

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

А всё почему? Потому что нарушен принцип единственной ответственности, ёпта! Класс должен делать что-то одно. Не тащи в него всё, что попадётся под руку. Сделай отдельный UserProfile, отдельный AuthCredentials, отдельный OrderHistory. Пусть каждый занимается своим делом, а не как эта мартышлюшка — и танцует, и поёт, и в уме числа перемножает.

Или вот ещё история: наследование. Ну, думаешь, о, сейчас я сделаю супер-пупер-базовый класс Vehicle, а от него унаследую Car, Bike, Spaceship. А потом выясняется, что у велосипеда нет двигателя, а метод start_engine() он всё равно наследует. И ты либо переопределяешь его, чтобы он выдавал raise NotImplementedError (что уже, блядь, криво), либо начинаешь городить хуй с винтом — промежуточные классы, миксины... В итоге получается иерархия, в которой разобраться может только тот, кто её писал, да и то через месяц уже ни хуя не помнит.

class Vehicle:
    def start_engine(self):
        print("Vroom vroom!")

class Bicycle(Vehicle):
    def start_engine(self):
        raise AttributeError("У меня нет двигателя, я ж велосипед, блядь!")

Вот это и есть классический пример «проблемы квадрата-прямоугольника». Кажется, что квадрат — это частный случай прямоугольника, но если у прямоугольника есть методы set_width и set_height, то для квадрата они ведут себя пиздец как странно. Наследование — не про «является», а про «может быть использован вместо». Если не уверен — лучше композицию, блядь. Чувствуешь подозрение, что наследование тут лишнее? Скорее всего, так и есть.

И главное — тестирование. Когда у тебя класс, который делает всё, протестировать его — это отдельный ад. Нужно mock'ить пол-вселенной, чтобы проверить один маленький метод. А если он разбит на маленькие, независимые модули, то и тесты пишутся за пять минут, и баги ловятся сразу. Волнение ебать, когда понимаешь, что из-за своей же поспешной архитектуры теперь нужно писать в десять раз больше тестового кода.

Короче, суть в чём: прежде чем нагородить очередной класс-бог, остановись и подумай, э, бошка, думай. «А действительно ли это одна ответственность? Не пытается ли этот объект жить за десятерых?» Спроси себя: «А что будет, если мне завтра нужно будет изменить вот эту часть? Придётся лезть в этот же класс?» Если ответ «да», то что-то пошло не так.

Помни, хорошая архитектура — это не когда нечего добавить, а когда нечего убрать. Всё должно быть на своих местах, как болты в двигателе. А не как в том анекдоте про чукчу и компьютер: «Хорошая вещь. И гвозди забивать можно, и как пресс использовать». Вот так и с классами-богами — вроде всё умеет, но нахуй никому не нужно. Чих-пых тебя в сраку с такой архитектурой!