Jeśli masz logikę, która musi być współużytkowana przez dwa kontrolery, gdzie ją trzymasz?


10

Mam zestaw funkcji jednego celu, których potrzebuję w dwóch osobnych kontrolerach. W tej chwili mam tylko zduplikowany kod i chcę się go pozbyć. Ten kod jest częścią kontrolera i nie należy do mojej warstwy usług. Gdzie byś to położył?


CakePHP nazywa je Komponentami: book.cakephp.org/2.0/en/controllers/components.html może to trochę inspiracja.
— Luc Franken

Odpowiedzi:


12

Nie powiedziałeś, jaką logikę udostępniasz. Krótko mówiąc, czy ta logika kontrolera czy funkcja pomocnika? Dwie metody radzenia sobie z tym w języku obiektowym to dziedziczenie i kompozycja. Dziedziczenie ma sens, jeśli między dwoma kontrolerami jest akcja wspólna. Kompozycja ma sens przez resztę czasu. Przykład zastosowania dziedziczenia znajduje się w mojej oryginalnej odpowiedzi poniżej dzielnika.

Często zdarza się, że klasa użyteczności lub klasa pomocnicza jest zależna od twojego frameworka. Na przykład w strukturach sieciowych Java i C # możesz mieć pakiet / przestrzeń nazw dla narzędzi. W Ruby on Rails możesz korzystać z Helperklasy dzielącej logikę między kontrolerami i widokami. Zasadniczo wyglądałoby to tak:

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

Alternatywnie możesz uczynić z niej klasę, którą tworzysz. Kluczem do powyższego wzorca klasy statycznej jest uczynienie funkcji czystymi funkcjami. Innymi słowy, przekazujesz w dowolnym stanie, który musi wykonać, a funkcja nie odwołuje się do żadnego innego stanu statycznego w systemie.

W obu przypadkach uzyskasz dostęp do każdego z kontrolerów w następujący sposób:

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

Oryginalna odpowiedź

Nie powiedziałeś, jaka była Twoja platforma, ponieważ może to wpłynąć na odpowiedź. Zakładając , że jest to język zorientowany obiektowo, najczęstszym podejściem jest utworzenie klasy podstawowej, którą rozszerzają oba kontrolery. Na przykład w Ruby on Rails możesz mieć:

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

class Controller1 < BaseController
    # ...
end

class Controller2 < BaseController
    # ...
end

Możesz przetłumaczyć ten pomysł na inne języki. To samo podejście będzie działać w przypadku ASP.NET MVC, Apache Wicket, Grails lub niemal każdej innej zorientowanej obiektowo struktury sieciowej. Jeśli twój język nie jest zorientowany obiektowo, to tak naprawdę zależy to od tego, w jaki sposób zaprojektowano framework, aby uzyskać najlepsze podejście.


3
Alternatywą jest umieszczenie logiki w osobnej klasie, a następnie utworzenie instancji tej klasy i wywołanie logiki z obu kontrolerów.
— Kramii

5
Tak, zawsze wolę kompozycję niż dziedziczenie
— Reno

1
Wykonaj sugestię Kramii zamiast dodawać dodatkową warstwę dziedzictwa. Ale myślę, że jego prawdziwe pytanie brzmiało, gdzie w rozwiązaniu idzie ta klasa.
— Nikt

1
Zależy to od funkcji i struktury. W szynach może należeć do klasy Helper. W programie ASP.NET lub Java może istnieć klasa narzędzi dla tego typu funkcji. To naprawdę zależy od tego, jak blisko kontrolera musi żyć.
— Berin Loritsch

To logika kontrolera. Po prostu potrzebuję go w dwóch miejscach. Teraz mam klasę rozszerzeń, której używam do umieszczenia logiki w jednym miejscu.
— Erin
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.