Wenn Sie eine Logik haben, die von zwei Controllern gemeinsam genutzt werden muss, wo bewahren Sie sie auf?

10

Ich habe eine Reihe von Einzweckfunktionen, die ich in zwei separaten Controllern benötige. Im Moment habe ich nur doppelten Code und möchte ihn loswerden. Dieser Code ist Teil des Controllers und gehört nicht zu meiner Serviceschicht. Wo würdest du es hinstellen?

Erin
quelle
CakePHP nennt sie Komponenten: book.cakephp.org/2.0/en/controllers/components.html Vielleicht ist das eine Inspiration.
Luc Franken

Antworten:

12

Sie haben nicht gesagt, welche Art von Logik Sie teilen. Kurz gesagt, ist diese Steuerlogik oder eine Hilfsfunktion? Die beiden Methoden, um in einer objektorientierten Sprache damit umzugehen, sind Vererbung und Komposition. Vererbung ist sinnvoll, wenn zwischen den beiden Controllern eine gemeinsame Aktion besteht. Komposition macht den Rest der Zeit Sinn. Das Beispiel für die Verwendung der Vererbung liegt in meiner ursprünglichen Antwort unter dem Teiler.

Es ist nicht ungewöhnlich, dass je nach Framework eine Utility-Klasse oder eine Helfer-Klasse vorhanden ist. In Java- und C # -Webframeworks verfügen Sie möglicherweise über ein Paket / einen Namespace für Dienstprogramme. In Ruby on Rails nutzen Sie möglicherweise die HelperKlasse, die die Logik zwischen Controllern und Ansichten teilt. Grundsätzlich würde es so aussehen:

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

Alternativ können Sie es zu einer Klasse machen, die Sie instanziieren. Der Schlüssel zum obigen statischen Klassenmuster besteht darin, Ihre Funktionen zu reinen Funktionen zu machen. Mit anderen Worten, Sie übergeben einen beliebigen Status, den es für seine Arbeit benötigt, und die Funktion verweist nicht auf einen anderen statischen Status im System.

In beiden Fällen würden Sie in jedem Ihrer Controller wie folgt darauf zugreifen:

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

Ursprüngliche Antwort

Sie haben nicht gesagt, was Ihre Plattform ist, da dies die Antwort beeinflussen kann. Unter der Annahme, dass es sich um eine objektorientierte Sprache handelt, besteht der häufigste Ansatz darin, eine Basisklasse zu erstellen, die beide Controller erweitern. In Ruby on Rails haben Sie beispielsweise Folgendes:

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

class Controller1 < BaseController
    # ...
end

class Controller2 < BaseController
    # ...
end

Sie können die Idee auch in andere Sprachen übersetzen. Der gleiche Ansatz funktioniert für ASP.NET MVC, Apache Wicket, Grails oder nahezu jedes andere objektorientierte Webframework. Wenn Ihre Sprache nicht objektorientiert ist, hängt es wirklich davon ab, wie das Framework für den besten Ansatz konzipiert ist.

Berin Loritsch
quelle
3
Die Alternative besteht darin, die Logik in einer separaten Klasse zu kapseln, diese Klasse dann zu instanziieren und die Logik von beiden Controllern aufzurufen.
Kramii
5
Ja, ich bevorzuge immer die Komposition gegenüber der Vererbung
Reno
1
Machen Sie Kramiis Vorschlag, anstatt eine zusätzliche Vererbungsebene hinzuzufügen. Aber ich denke, seine eigentliche Frage war, wohin in der Lösung diese Klasse geht.
Niemand
1
Es hängt von der Funktion und dem Rahmen ab. In Schienen könnte es in die Helper-Klasse gehören. In ASP.NET oder Java verfügen Sie möglicherweise über eine Dienstprogrammklasse für diesen Funktionstyp. Es hängt wirklich davon ab, wie nahe es dem Controller kommt, um zu leben.
Berin Loritsch
Es ist Controller-Logik. Ich brauche es einfach an zwei Stellen. Was ich jetzt habe, ist eine Erweiterungsklasse, mit der ich die Logik an einem Ort platziere.
Erin