Se hai un pezzo di logica che deve essere condiviso tra due controller, dove lo conservi?


10

Ho un set di funzioni monouso di cui ho bisogno in due controller separati. In questo momento ho solo un codice duplicato e voglio liberarmene. Questo codice fa parte del controller e non appartiene al mio livello di servizio. Dove lo metteresti?


CakePHP li chiama Componenti: book.cakephp.org/2.0/it/controllers/components.html forse questa è una fonte d'ispirazione.
Luc Franken,

Risposte:


12

Non hai detto che tipo di logica stai condividendo. In breve, questa logica del controller o una funzione di supporto? I due metodi per affrontarlo in un linguaggio orientato agli oggetti sono ereditarietà e composizione. L'ereditarietà ha senso se esiste un'azione condivisa tra i due controller. La composizione ha senso per il resto del tempo. L'esempio dell'utilizzo dell'eredità si trova nella mia risposta originale sotto il divisore.

Non è raro avere una classe di utilità o una classe di supporto a seconda del framework. Ad esempio, nei framework Web Java e C # potresti avere un pacchetto / spazio dei nomi per le utility. In Ruby on Rails, potresti trarre vantaggio dalla Helperclasse che condivide la logica tra controller e viste. Fondamentalmente, sarebbe simile a questo:

// NOTE: group similar functions
static class LoginUtility
{
    static bool IsLoggedIn(Request request) { /* ... */ }
}

In alternativa, puoi renderlo una classe che crei un'istanza. La chiave per il modello di classe statica sopra è rendere le tue funzioni pure funzioni. In altre parole, si passa in qualsiasi stato in cui è necessario svolgere il proprio lavoro e la funzione non fa riferimento a nessun altro stato statico nel sistema.

In entrambi i casi, accederai ad ognuno dei tuoi controller in questo modo:

void MyAction()
{
    if (LoginUtiltiy.IsLoggedIn(Request))
    {
        // Do something ...
    }
}

Risposta originale

Non hai detto quale fosse la tua piattaforma, poiché ciò può influire sulla risposta. Supponendo che si tratti di un linguaggio orientato agli oggetti, l'approccio più comune è quello di creare una classe base estesa da entrambi i controller. Ad esempio in Ruby on Rails potresti avere:

class BaseController < ApplicationController
    def my_special_function
        # ...
    end
end

class Controller1 < BaseController
    # ...
end

class Controller2 < BaseController
    # ...
end

Puoi tradurre l'idea anche in altre lingue. Lo stesso approccio funzionerà con ASP.NET MVC, Apache Wicket, Grails o qualsiasi altro framework web orientato agli oggetti. Se la tua lingua non è orientata agli oggetti, dipende davvero da come il framework è progettato per l' approccio migliore .


3
L'alternativa è incapsulare la logica in una classe separata, quindi creare un'istanza di quella classe e chiamare la logica da entrambi i controller.
Kramii,

5
Sì, preferisco sempre la composizione rispetto all'eredità
Reno,

1
Esegui il suggerimento di Kramii piuttosto che aggiungere un ulteriore livello di eredità. Ma penso che la sua vera domanda fosse: dove nella soluzione va quella classe.
Nessuno il

1
Dipende da quale sia la funzione e il framework. In rotaie, potrebbe appartenere alla classe Helper. In ASP.NET o Java, potresti avere una classe di utilità per quel tipo di funzione. Dipende davvero da quanto vicino al controller deve vivere.
Berin Loritsch,

È la logica del controller. Mi capita di averne bisogno in due posti. Quello che ho ora è una classe di estensione che uso per mettere la logica in una posizione.
Erin,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.