Metodo privato con un argomento derivabile - un odore di codice?

1

Stiamo implementando un servizio per la creazione di un abbonamento in cui l'abbonamento può essere collegato a un ordine. Sfondo rapido: lo scopo di questo servizio è di consentire al cliente di ricevere l'articolo a cui si è abbonati il prima possibile. La soluzione che abbiamo scelto è quella di creare un ordine separato per il primo elemento prima dell'avvio della sua sottoscrizione "reale".

Ecco uno snippet della classe di servizio. Ho abbreviato il nome del metodo directive per rimuovere i dettagli estranei dal frammento:

class Subscription
  belongs_to :order
end

class SubscriptionCreator
  def call
    # ...
    return directive if directive.is_a?(String)

    # ...

    subscription = create_subscription(order: directive)
    # ...
  end

  private

  def create_subscription(order: nil)
    subscription = Subscription.new

    # ...

    subscription.order = order if order

    subscription.save!

    subscription
  end

  def directive
    # Return values:
    #   * Successful: the order created.
    #   * Error: An error message string.
    #   * Not applicable: nil.
  end
end

Ecco le parti principali del servizio:

  1. SubscriptionCreator#call è il punto di ingresso.
  2. SubscriptionCreator#directive crea l'ordine, se applicabile.
  3. SubscriptionCreator#create_subscription crea la sottoscrizione e la lega all'ordine se ne è stata creata una.

Mi sono preoccupato dell'argomento order di create_subscription poiché create_subscription può chiamare direttamente il metodo directive . Quindi ho proposto questo cambiamento:

def call
  # ...
  return directive if directive.is_a?(String)

  # ...

  # No longer has order argument.
  subscription = create_subscription
  # ...
end

def create_subscription
  subscription = Subscription.new

  # ...

  subscription.order = directive if directive

  subscription.save!

  subscription
end

Tuttavia, l'autore del servizio preferisce il codice originale. Sostiene che è meglio che create_subscription non conosca la logica per creare l'ordine, cioè non conosca il metodo directive . Quella logica che dice dovrebbe appartenere al metodo call .

Sostiene che con il codice originale, sarebbe più facile spostare create_subscription da qualche altra parte perché non conterrebbe alcuna logica specifica di dominio. Aggiunge che mantenere gli strati di livello inferiore liberi dalla logica del dominio renderebbe i metodi più modulari e quindi più riutilizzabili e più facili da estrarre.

Da parte mia, penso che la rimozione dell'argomento assicuri che create_subscription abbia solo una fonte di informazioni per l'ordine creato. Nel codice originale, c'è il rischio che l'ordine passato a create_subscription non sia lo stesso del risultato di directive .

Quindi, quali sono le conseguenze di mantenere / rimuovere l'argomento dal metodo privato?

    
posta gsmendoza 15.08.2015 - 07:56
fonte

1 risposta

2

La tua iscrizione è associata a 0 o 1 ordini. Da dove gli ordini provengono non ha importanza per l'Abbonamento, quindi passare un ordine a create_subscription sembra ragionevole.

Nel primo frammento, l'attività di recupero o creazione dell'ordine appropriato è separata dall'attività di creazione dell'abbonamento. Nel secondo, il recupero / creazione dell'Ordine è incorporato nella creazione di un Abbonamento, e non vedo ciò che guadagni. Se mai, rende il codice più difficile da modificare: cosa succede se cambi il modo in cui recuperi gli ordini e se ci fosse più di un modo per recuperare un ordine?

Il primo frammento separa l'attività di recupero degli ordini dall'attività di creazione di sottoscrizioni e questa separazione dei problemi renderebbe il codice più facile da mantenere, penso.

    
risposta data 15.08.2015 - 18:04
fonte

Leggi altre domande sui tag