Si vous avez un morceau de logique qui doit être partagé entre deux contrôleurs, où le conservez-vous?

10

J'ai un ensemble de fonctions à usage unique dont j'ai besoin dans deux contrôleurs distincts. Pour le moment, je n'ai qu'un code en double et je veux m'en débarrasser. Ce code fait partie du contrôleur et n'appartient pas à ma couche de service. Où le mettriez-vous?

Erin
la source
CakePHP les appelle Composants: book.cakephp.org/2.0/en/controllers/components.html c'est peut-être une inspiration.
Luc Franken

Réponses:

12

Vous n'avez pas dit quel genre de logique vous partagez. En bref, est-ce une logique de contrôleur ou une fonction d'assistance? Les deux méthodes pour gérer cela dans un langage orienté objet sont l'héritage et la composition. L'héritage a du sens s'il y a une action partagée entre les deux contrôleurs. La composition a du sens le reste du temps. L'exemple de l'utilisation de l'héritage réside dans ma réponse originale sous le diviseur.

Il n'est pas rare d'avoir une classe utilitaire ou une classe d'assistance selon votre framework. Par exemple, dans les frameworks Web Java et C #, vous pouvez avoir un package / espace de noms pour les utilitaires. Dans Ruby on Rails, vous profitez peut-être de la Helperclasse qui partage la logique entre les contrôleurs et les vues. Fondamentalement, cela ressemblerait à ceci:

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

Alternativement, vous pouvez en faire une classe que vous instanciez. La clé du modèle de classe statique ci-dessus est de faire de vos fonctions des fonctions pures. En d'autres termes, vous passez dans n'importe quel état dont il a besoin pour faire son travail, et la fonction ne fait référence à aucun autre état statique du système.

Dans les deux cas, vous y accéderez dans chacun de vos contrôleurs comme ceci:

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

Réponse originale

Vous n'avez pas dit quelle était votre plateforme, car cela peut affecter la réponse. En supposant qu'il s'agit d'un langage orienté objet, l'approche la plus courante consiste à créer une classe de base que les deux contrôleurs étendent. Par exemple, dans Ruby on Rails, vous pourriez avoir:

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

class Controller1 < BaseController
    # ...
end

class Controller2 < BaseController
    # ...
end

Vous pouvez également traduire l'idée dans d'autres langues. La même approche fonctionnera pour ASP.NET MVC, Apache Wicket, Grails ou à peu près tout autre framework Web orienté objet. Si votre langage n'est pas orienté objet, alors cela dépend vraiment de la façon dont le framework est conçu quant à la meilleure approche.

Berin Loritsch
la source
3
L'alternative consiste à encapsuler la logique dans une classe distincte, puis à instancier cette classe et à appeler la logique à partir des deux contrôleurs.
Kramii
5
Ouais, je préfère toujours la composition à l'héritage
Reno
1
Faites la suggestion de Kramii plutôt que d'ajouter une couche supplémentaire d'héritage. Mais je pense que sa véritable question était de savoir où allait la solution.
Personne
1
Cela dépend de la fonction et du cadre. Dans les rails, il peut appartenir à la classe Helper. Dans ASP.NET ou Java, vous pouvez avoir une classe utilitaire pour ce type de fonction. Cela dépend vraiment de la proximité du contrôleur dont il a besoin pour vivre.
Berin Loritsch
C'est la logique du contrôleur. Il se trouve que j'en ai besoin à deux endroits. Ce que j'ai maintenant est une classe d'extension que j'utilise pour mettre la logique en un seul endroit.
Erin