Eu tenho uma lista suspensa que exibe valores de uma tabela para o usuário final. Eu gostaria que esses valores fossem classificados em ordem alfabética.
De acordo com o design adequado do MVC, em que camada devo colocar minha lógica de classificação: o modelo, a visualização ou o controlador?
Edição : Em resposta à pergunta de LarsH, "Você quer dizer código que determina qual ordem de classificação é desejada? Ou código que executa a classificação?", Eu estava originalmente me referindo ao código que determina qual ordem de classificação é desejada.
asp.net-mvc
model-view-controller
Ryan Kohn
fonte
fonte
Respostas:
(Nota: esta citação e citação é retirada da resposta de @ dasblinkenlight , mas discordamos de nossa interpretação. Leia o post dele e decida -se).
De acordo com a descrição do MVC ,
A lógica de classificação (por exemplo, o comparador de classificação / algoritmo de classificação) pertence ao modelo, pois contém regras de negócios e dados de estado. Como alterar a maneira como os dados do modelo são classificados se enquadra na categoria "alterar a apresentação da visualização do modelo", o controlador é responsável por "fazer a classificação" chamando o método model.changeSortedState ().
fonte
public void Sort(bool sortByDescending = false)
, onde, se falso, classifica por ascensão. Ou apenas tenha dois métodos de classificação diferentes se a lógica for muito diferente.Quem controla a ordem de classificação?
(Da Wikipedia )
1) Ordem natural dentro dos próprios dados:
O pedido faz parte do modelo, portanto deve ir para lá. Uma solicitação bruta de "todos os dados" retornaria os dados na ordem de classificação e não há interface para escolher a ordem de classificação.
2) O usuário deve controlar como eles vêem os dados:
A Visualização forneceria uma interface (como setas ascendentes / descendentes) que interagem com o Controlador, e o Modelo entende os dados suficientemente bem para fazer a classificação solicitada nos dados. No entanto, uma atração bruta dos dados não precisa necessariamente ser classificada, ao contrário de (1).
Em ambos os casos,
A Visualização não entende que há uma classificação em andamento, além da capacidade de mostrar qual direção de classificação foi escolhida. Não coloque a lógica lá.
Advertência pequena
A funcionalidade de classificação pode ser puramente visualizada, sob uma circunstância (que eu possa pensar de antemão; pode haver mais):
Uma classificação "burra" em que todos os dados já estão na exibição e não precisa usar nenhum conhecimento de domínio para fazer a classificação. Comparação de números ou seqüências muito simples, por exemplo. Isso não é possível, por exemplo, nos resultados de pesquisa em uma página da Web quando é provável que os resultados sejam divididos em várias páginas.
fonte
De acordo com a descrição do MVC ,
De acordo com isso, a lógica de classificação pertence ao controlador, porque alterar a maneira como os dados do modelo são classificados cai diretamente na categoria "alterar a apresentação da exibição do modelo".
EDIT: Para esclarecer vários mal-entendidos expressados nos comentários, a "lógica de classificação" não é o código que executa a classificação; é o código que define a classificação. A lógica de classificação compara itens individuais entre si para estabelecer uma ordem (por exemplo, através de uma instância de
IComparator<T>
) ou contém lógica que constrói um objeto a ser usado para fazer pedidos por um sistema externo (por exemplo, através de uma instância deIOrderedQueryable<T>
). Essa lógica pertence ao seu controlador, porque precisa de conhecimento relacionado ao lado "comercial" do seu aplicativo. É inteiramente suficiente executar a classificação, mas é separado do código que realmente executaisto. O código que classifica pode estar na sua visão, no seu modelo ou até na camada de persistência que apóia o seu modelo (por exemplo, seu banco de dados SQL).fonte
IComparer<T>
. A "mecânica padrão" restante da classificação, incluindo a recuperação de dados do modelo, está de acordo com a visão.{Unknown, Pass, Fail}
. Além disso, suponha queUnknown
deve sempre classificar por último, independentemente da ordem crescente ou decrescente que o usuário escolheu. A colocação dessa lógica na visualização informaria muito a sua visão sobre a natureza comercial dos dados dentro docode
campo. A visualização não deve saber disso: tudo o que se sabe é que o usuário executou um gesto de "classificação" (por exemplo, clicou em um cabeçalho); o resto é com o controlador.Nenhuma das acima. A classificação é lógica de negócios e a lógica de negócios não pertence a nenhum dos três. Nem todo código no seu aplicativo será um modelo, visualização ou controlador.
O que geralmente faço nos meus aplicativos MVC é que tenho uma camada de serviço que executa toda a lógica de negócios. Os métodos na camada de serviço devem ter uma API simples e limpa, com parâmetros bem nomeados. Em seguida, você pode chamar esses métodos do seu controlador para manipular os dados nos modelos.
Nesse sentido, a classificação está "no controlador", mas o próprio código que faz a classificação não deve ser implementado no controlador, apenas invocado a partir daí.
fonte
Definitivamente não é o controlador: ele envia mensagens para visualizar e modelar, mas deve fazer o mínimo possível de trabalho. Se o usuário puder alterar a classificação, a solicitação será tratada pelo controlador, informando o modelo ou a visualização sobre ele.
Talvez o View seja uma coisa pura do View. Se o Aplicativo funcionar tão bem sem classificação, a classificação é apenas parte da representação e deve ser exibida.
Se a ordem é parte inerente do domínio, ela deve ser inserida no modelo.
fonte
Portanto, a escolha é: você acha que isso faz parte da lógica de negócios do domínio ou da lógica de apresentação.
Se você estivesse implementando um padrão MVC Model2 ou MVC clássico adequado, eu diria que a ordem dos dados fornecidos pela camada do modelo deve ser acionada pela solicitação da visualização para a camada do modelo. O View solicita dados ordenados, a camada do modelo fornece.
Porém, como você está usando a interpretação do padrão MVC do ASP.NET MVC, que é um pouco diferente do seu MVC padrão - a instância do ViewModel deve solicitar informações ordenadas da camada do modelo (por algum motivo, a estrutura do ASP.NET acha que os modelos devem ser chamados "views" e views devem ser chamadas de "viewmodels" (é estranho).
fonte
Eu normalmente faria isso no controlador para permanecer alinhado com o padrão conforme as outras respostas. Veja abaixo o raciocínio.
Estive refletindo sobre isso e lendo as respostas e o material relacionado, e falando pragmaticamente, eu diria que isso dependeria da sua aplicação, por exemplo:
É um aplicativo médio / grande e / ou possui várias UIs associadas (por exemplo, um aplicativo do Windows, interface da Web e interface do telefone).
Se é um site de interface do usuário única bem definido e você está usando algo como EF Code First e não tem ou não tem intenção de criar uma camada de serviço e planeja usar um método de extensão simples e imediato para obtê-lo:
Se for o mesmo que o anterior, MAS não pode ser implementado com um método de extensão pronto para uso.
Resumindo:
Resposta dogmática: Camada de Serviço
Resposta pragmática: geralmente o controlador
fonte
Sugiro que classificar os dados de uma tabela - dados pequenos o suficiente para serem úteis em uma lista suspensa - devam vir do banco de dados já classificado por meio da consulta. Para mim, isso faz do modelo o local em que a classificação é aplicada.
Se você está determinado a fazer a classificação manualmente, acho que existem bons argumentos para usar o modelo ou o controlador como seu local preferido para a lógica. A limitação seria sua estrutura específica. Eu prefiro gerenciar dados apenas no modelo. Eu uso o controlador para casar dados (modelo) e apresentação (exibição), como aprendi (auto).
fonte
Embora eu concorde, em princípio, com a idéia de que a classificação é Business Logic, porque, ao dividir sua origem, você terminaria com algo como "O cliente gostaria que a página do produto fosse exibida com as imagens classificadas por data", então fica claro que a ordem de classificação dos dados geralmente não é arbitrária - mesmo se não houver classificação, pois ainda é uma decisão comercial por omissão (uma lista vazia ainda é uma lista).
MAS ... Essas respostas parecem não levar em conta os avanços na tecnologia ORM, só posso falar em relação ao Entity Framework (vamos evitar uma discussão sobre se isso é verdadeiro ORM, esse não é o ponto) da Microsoft como é isso que eu uso, mas tenho certeza de que outros ORMs oferecem funcionalidade semelhante.
Se eu criar uma exibição fortemente tipada para uma classe de produto usando o MS MVC e o Entity Framework e houver um relacionamento de chave estrangeira entre a tabela Product e Image (por exemplo, FK_Product_Image_ProductId), seria possível classificar rapidamente as imagens durante a exibição usando algo parecido com isto na exibição:
Houve menção a uma camada específica de lógica de negócios, que eu também uso para executar 80% da minha lógica de negócios, mas não gravarei funcionalidade de classificação na camada de lógica de negócios que imite algo que vem pronto para uso do Entity Framework.
Acho que não há uma resposta correta para essa pergunta, além de dizer isso; você deve abstrair lógica de negócios complexa sempre que possível, mas não ao custo de reinventar a roda.
fonte
myList.OrderBy(x => x.CreationDate)
- realmente não há necessidade de introduzir nenhuma camada extra desnecessária apenas para fazer isso. Para adicionar isso, o que eles fariam se precisassem de dados paginados e classificados? Consulte a tabela inteira, classifique-a e mantenha o que eles precisam? Pode-se simplesmente ligarmyList.OrderBy(x => x.Date).Skip((page-1)*pageSize).Take(pageSize)
e nenhum dado desnecessário é recuperado.Suponha que você tenha o site MVC, o site WebForms e um aplicativo móvel.
Se você deseja que a classificação seja consistente entre essas camadas de apresentação, diria que você deve classificar fora da camada de apresentação. O serviço seria um bom candidato.
Caso contrário, eu armazenaria essa lógica em um modelo de exibição. Por quê? Porque será reutilizável e facilmente testável.
fonte
Dos três que você listou, eu diria que ele pertence ao controlador. Eu realmente não gosto de colocar esse tipo de lógica no controlador, no entanto. Normalmente, crio uma camada de serviço com a qual o controlador se comunica, que será responsável pela comunicação com o armazenamento de dados e pelo manuseio da lógica de classificação. Para pequenas aplicações, é bom ficar no controlador.
fonte
Esta é uma pergunta feita com o asp.net em mente, mas como alguém mencionou o Rails, pensei que seria interessante considerar o problema nesse contexto. No Rails, é natural e bastante comum executar a classificação juntamente com a recuperação como uma ação do controlador, uma vez que a estrutura e a API do ActiveRecord / ActiveQuery o fornecem. Por outro lado, é possível definir algum tipo de ordem de classificação personalizada para itens estáticos e colocá-la no modelo a ser usado pelo controlador, para que o modelo possa desempenhar um papel na lógica de classificação, mesmo que não execute a operação diretamente. Seja o que for, pode ser seguro dizer que colocar a lógica de classificação na visão geralmente é desaprovada.
Estou um pouco divertido porque algumas respostas são absolutamente contra colocar o tipo no controlador ou no modelo, e as acho muito pedantes para o meu gosto, mas suponho que isso dependa da natureza da estrutura usada e das convenções usuais associadas isto. Também concordo com o comentário de Bill K de que ter a separação em primeiro lugar é mais importante.
fonte