@evomed

Как назвать классы заказа для паттерна «Состояние»?

Есть заказ. Модель Order. Он имеет два состояния - платный заказ (сумма больше нуля) и бесплатный (сумма равна нулю). В зависимости от типа заказа применяется в сервисе разная логика. Хочу применить паттерн состояние, но не могу понять как это состояние называется? На данный момент все что придумал это абстрактный класс MoneyState и два класса-состояния с логикой HasMoney и NoMoney. Но вот мне нужно заюзать в них метод getRedirectUrl и связка $money->getRedirectUrl() выглядит нечитабельной. Как назвать это состояние и классы?
  • Вопрос задан
  • 233 просмотра
Решения вопроса 1
sfi0zy
@sfi0zy
Creative frontend developer
Попробуйте вместо попыток натянуть сову на глобус, а задачу на паттерн, действовать от простого. Пусть заказ бывает бесплатным. У заказа есть флаг "является ли он бесплатным". Мы даже можем воспользоваться возможностями языка и прикрутить какой-то геттер для надежности, чтобы флаг менялся в зависимости от устанавливаемой цены (в примерах условно JS):
class Order {
    get isFree() { return this.price === 0; }
}

Мы можем прям сюда присобачить и оплату, но допустим мы не хотим, чтобы заказ что-то знал об урлах для оплаты. Ему это не надо. Заказ - это список товаров, какой-то статус завершенности, адрес доставки и.т.д. Он про данные, не про процессы. Путь будет обработчик, который может провести заказ как кассир в пятерочке:
class Order { /* --- */ }

class Сashier {
    proceed(order) {
        const url = order.isFree ? "free url" : "paid url";
        // ...редиректим, проводим оплату, предлагаем пакетик и кофе по акции
    }
}

Допустим у нас есть много платежных систем, там все сложно. Инфраструктура - не кассира дело. Ок, дадим ему доступ к адаптеру, который скрывает все за собой и проводит непосредственно оплату.
class Order { /* --- */ }

class PaymentHandler {
    charge(price) {
        // ...редиректим куда надо, в зависимости от цены и привязанной карты
    }
}

class Cashier {
    proceed(order) {
        const isSuccess = PaymentHandler.charge(order.price);
        
        if (isSuccess) {
            // заказ прошел
        } else {
            throw new Error('ГААААААЛЯЯЯ ОТМЕЕЕЕНА!!!!');
        }
    }
}

Получается четкое разделение ролей. Заказ - про данные, кассир - про процесс, обработчик оплаты - про муть с платежными системами. Возможно, что даже флаг isFree не особо нужен у заказа. И, возможно, что к паттерну "состояние" мы не придем, потому что он в первую очередь решает проблему бесконечного количества комбинаций флагов, но если нет флагов, то нет и проблемы. И.т.д. Развивайте конструкции по мере их естественного появления. Тогда проблем с именованием будет на порядок меньше. Потому что каждое слово в коде отражает какую-то заранее сформированную сущность в алгоритмах в голове.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@Everything_is_bad
В компьютерных науках есть только две сложные проблемы – инвалидация кэша и именование переменных
называй как тебе будет понятней, с опытом будешь точнее попадать.

это абстрактный класс MoneyState и два класса-состояния с логикой HasMoney и NoMoney.
не видя общую картинку как ты у тебя там выдаются названия, можно предлагать как OrderState, StandartOrderState и FreeOrderState, так и BaseState, State и FreeState, и т.д, и т.п.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы