Inversione del controllo nel controller da parte di un mediatore

1

Un utente deve eseguire un'attività alquanto complessa sul mio sito Web (inviare una valutazione). Per fare un esempio, consideriamo che si tratta di una valutazione per un film, fatta attraverso un controller. Ci sono diversi possibili "percorsi" che la logica potrebbe seguire

  • L'utente desidera annullare la sua sottomissione (ad es. non è andato al film)
    • Fornisce tutti i parametri richiesti OPPURE
  • L'utente invia l'invio del voto
    • Fornire tutti i parametri richiesti OPPURE
  • L'utente aveva già inviato la sua valutazione (e gli è stata negata l'azione)
  • Altri motivi (ad es. filmato, ecc.)

Sto cercando di incapsulare tutta la logica in un servizio / mediatore, così posso anche riutilizzare la logica al di fuori di un controller (ad esempio in una console operativa).

Ho deciso di fare del controller un argomento durante questa installazione di RatingService, e questo si sta trasformando in una inversione di controllo / il servizio fa tutto. Il mio servizio conosce lo stato in cui si trova attualmente e attiva vari richiami (notifica, tracciamento, ecc.) Incluso il rendering di "flash" per l'utente tramite il controller.

Questo inizia ad avere un odore strano dato che il mio servizio si sta lentamente impossessando del controller per se stesso.

Sto mostrando un codice di esempio (Ruby on Rails) solo per illustrare il mio punto

class ReviewController
  def review
     ReviewService.review(reviewable, current_user, 
                          controller: self, **review_params)
  end
end

class ReviewService
  def review
     ...
  end

  private

  def cancelled_submission?
    ...
    controller.flash(I18n.t(:cancelled)) if controller.present?
  end

  def submit_rating
    ...
    controller.flash(I18n.t(:rating_submitted)) if controller.present?
  end

  def already_submitted
    ...
    controller.flash(I18n.t(:already_submitted)) if controller.present?
  end
end

Mi chiedo se sarebbe una buona pratica considerare una completa inversione di controllo e dichiarare solo metodi nel mio controller che possono essere utilizzati nel servizio.

Cioè, gira

class ReviewController
  def review
     ...
  end
end

class ReviewService
  def review
     ...
  end

  private

  def cancelled_submission?
    ...
    controller.flash(I18n.t(:cancelled)) if controller.present?
  end
end

In

class ReviewController
  def review
     ...
  end

  # Public method, meant to be called back from the service in an inversion of control fashion
  def notify_cancelled
    flash(I18n.t(:cancelled)
  end
end

class ReviewService
  def review
     ...
  end

  private

  def cancelled_submission?
    ...
    controller.notify_cancelled if controller.present?
  end
end

.. o se ci sono buone pratiche là fuori

    
posta Cyril Duchon-Doris 06.04.2017 - 12:49
fonte

0 risposte

Leggi altre domande sui tag