За последние 24 часа нас посетили 22286 программистов и 1185 роботов. Сейчас ищут 756 программистов ...

Вопрос о правильности архитектуры (laravel)

Тема в разделе "Прочие вопросы по PHP", создана пользователем equentor, 24 апр 2017.

Метки:
  1. equentor

    equentor Новичок

    С нами с:
    20 апр 2017
    Сообщения:
    4
    Симпатии:
    0
    Есть 2 сущности, User и Product. User реализует интерфейс BuyerInterface.

    PHP:
    1. interface BuyerInterface
    2. {
    3.     public function canBuy(Product $product): bool;
    4. }
    Тут понятно. Вопрос в следующем: где правильнее описывать метод buy()?
    У меня 2 варианта приходят на ум:
    1. Описать метод buy() в модели:

    PHP:
    1. class User extends Model implements BuyerInterface
    2. {
    3.     public function canBuy(Product $product): bool
    4.     {
    5.         return $product->cost <= $this->money;
    6.     }
    7.  
    8.     public function buy(Product $product)
    9.     {
    10.         if ($this->canBuy($product)) {
    11.             //...do something
    12.         } else {
    13.             throw new NotEnoughMoneyException();
    14.         }
    15.     }
    16. }
    17.  
    18. // controller
    19.  
    20. try {
    21.     $user->buy($product);
    22. } catch(NotEnoughtMoneyException $ex) {
    23.     //...do something
    24. }
    И второй вариант - создать сервис, в котором будет метод:
    PHP:
    1. class TradeService
    2. {
    3.     public function buy(BuyerInterface $user, Product $product)
    4.     {
    5.         if ($user->canBuy($product)) {
    6.             //...покупка
    7.         } else {
    8.             throw new NotEnoughMoneyException();
    9.         }
    10.     }
    11. }
    12.  
    13. // controller
    14.  
    15. try {
    16.     $tradeService->buy($user, $product);
    17. } catch(NotEnoughMoneyException $ex) {
    18.     //...do something
    19. }
    Как будет лучше с вашей точки зрения? Я склоняюсь к сервису, т.к. позволяет избежать дубляжа кода метода buy() на случай если появится ещё одна сущность, реализующая контракт BuyerInterface. Да и к тому же метод buy() это не прерогатива сущности, от неё нам нужен только контракт на покупку.
     
    #1 equentor, 24 апр 2017
    Последнее редактирование: 24 апр 2017
  2. Zuldek

    Zuldek Старожил

    С нами с:
    13 май 2014
    Сообщения:
    2.381
    Симпатии:
    344
    Адрес:
    Лондон, Тисовая улица, дом 4, чулан под лестницей
    По текущей реализации метод бай лишний в абстракции трейд-сервис. Если действительно сущностей реализующих интерфейс байера неопределенное число и объект юзер не только и не обязательно будет в их числе, то да - вынос метода в абстракцию оправдан но я бы реализовал метод в трейте если нет других уточнений
     
    #2 Zuldek, 24 апр 2017
    Последнее редактирование: 24 апр 2017