Se você tem um pedaço de lógica que precisa ser compartilhado entre dois controladores, onde você o guarda?

10

Eu tenho um conjunto de funções de propósito único que preciso em dois controladores separados. No momento, só tenho código duplicado e quero me livrar dele. Este código faz parte do controlador e não pertence à minha camada de serviço. Onde você colocaria isso?

Erin
fonte
O CakePHP os chama de Componentes: book.cakephp.org/2.0/en/controllers/components.html talvez seja alguma inspiração.
precisa

Respostas:

12

Você não disse que tipo de lógica está compartilhando. Em resumo, essa lógica do controlador é uma função auxiliar? Os dois métodos de lidar com isso em uma linguagem orientada a objetos são herança e composição. A herança faz sentido se houver uma ação compartilhada entre os dois controladores. A composição faz sentido o resto do tempo. O exemplo do uso de herança está na minha resposta original abaixo do divisor.

Não é incomum ter uma classe de utilitário ou auxiliar, dependendo da sua estrutura. Por exemplo, nas estruturas da web Java e C #, você pode ter um pacote / namespace para utilitários. No Ruby on Rails, você pode estar aproveitando a Helperclasse que compartilha lógica entre controladores e visualizações. Basicamente, ficaria assim:

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

Como alternativa, você pode criar uma classe que você instancia. A chave para o padrão de classe estática acima é tornar suas funções funções puras. Em outras palavras, você passa em qualquer estado em que ele precise executar seu trabalho, e a função não faz referência a nenhum outro estado estático no sistema.

Em qualquer um dos casos, você o acessaria em cada um de seus controladores como este:

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

Resposta original

Você não disse qual era a sua plataforma, pois isso pode afetar a resposta. Supondo que seja uma linguagem orientada a objetos, a abordagem mais comum é criar uma classe base que os dois controladores estendem. Por exemplo, no Ruby on Rails, você pode ter:

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

class Controller1 < BaseController
    # ...
end

class Controller2 < BaseController
    # ...
end

Você pode traduzir a ideia para outros idiomas também. A mesma abordagem funcionará para o ASP.NET MVC, Apache Wicket, Grails ou qualquer outra estrutura da Web orientada a objetos. Se sua linguagem não é orientada a objetos, isso realmente depende de como a estrutura é projetada quanto à melhor abordagem.

Berin Loritsch
fonte
3
A alternativa é encapsular a lógica em uma classe separada, instanciar essa classe e chamar a lógica dos dois controladores.
Kramii
5
Yup eu sempre favorecer composição sobre herança
Reno
11
Faça a sugestão de Kramii em vez de adicionar uma camada extra de herança. Mas acho que a pergunta real foi para onde a solução vai nessa aula.
Ninguém
11
Depende de qual é a função e a estrutura. Nos trilhos, ele pode pertencer à classe Helper. No ASP.NET ou Java, você pode ter uma classe de utilitário para esse tipo de função. Realmente depende de quão perto do controlador ele precisa viver.
Berin Loritsch 29/03
É lógica do controlador. Eu só preciso disso em dois lugares. O que eu tenho agora é uma classe de extensão que eu uso para colocar a lógica em um local.
Erin