Padrão MVC no Android

497

É possível implementar o padrão model-view-controller em Java para Android?

Ou já está implementado por meio de atividades? Ou existe uma maneira melhor de implementar o padrão MVC para Android?

Mohit Deshpande
fonte
64
Sua pergunta é muito boa. Mas a resposta marcada como solução não está correta na minha opinião. Pode desencaminhar várias pessoas.
Saghar
4
Confira meus 2 posts que começam aqui Android Architecture: MV?
Dori
1
Também existe um conjunto extra de regras a seguir para aderir ao MVC ou o desenvolvimento do Android já foi adaptado ao MVC por causa de Atividade, XML, Recursos?
Flame of udun
3
@Dori, eu conserto o seu link: Arquitetura do Android: MV?
precisa saber é o seguinte
Este artigo corresponde exatamente o que você está procurando, MVC no android através de um exemplo prático: digigene.com/architecture/android-architecture-part-2-mvc
Ali Nem

Respostas:

239

No Android, você não possui MVC, mas possui o seguinte:

  • Você define sua interface do usuário em vários arquivos XML por resolução, hardware etc.
  • Você define seus recursos em vários arquivos XML por localidade etc.
  • Você estende classes como ListActivity , TabActivity e utiliza o arquivo XML por inflaters .
  • Você pode criar quantas classes desejar para sua lógica de negócios.
  • Muitos Utils já foram escritos para você - DatabaseUtils, Html.
Pentium10
fonte
3
@JDPekham, por que você diz "Você não pode instanciar uma atividade sem falar com seu layout / exibição"? A instanciação de uma atividade não requer conversação com visualizações, na verdade, conversar com visualizações não faz parte da instanciação de Atividade. Você PODE (mas não precisa) chamar vários métodos de Atividade que interagem com suas visualizações quando e se achar necessário. Segunda pergunta: supondo que a Activity pretenda assumir o papel de "controlador" (acredito que muitos desenvolvedores do Android veem dessa maneira) por que não falar com seus pontos de vista da Activity?
8
Para quem diz que "Android é MVC", tente Backbone.js (sim, js do lado do cliente) por uma semana e depois volte e diga "Android Android é MVC". Você finalmente vai entender a pergunta e por isso que continuamos a pedir :)
Mark Peterson
14
"No Android você não tem MVC" ???? No Android, como em outros idiomas, você tem o MVC, se quiser.
Lorenzo Barbagli
1
@LorenzoBarbagli Ele quer dizer que o Android não aplica o MVC nos aplicativos por design (como o iOS). Você precisa implementar uma variedade de MVC, MVP ou qualquer outra coisa para obter o que o MVC fornece - ou seja, separação de preocupações e um Modelo isolado e facilmente testável.
Piovezan
Não. Definitivamente, existe MVC no Android, mas de forma mais implícita. É apenas implementado de uma maneira diferente, de acordo com a estrutura do Android.
6rchid
229

Não há um padrão MVC universalmente exclusivo. MVC é um conceito e não uma estrutura de programação sólida. Você pode implementar seu próprio MVC em qualquer plataforma. Contanto que você se atenha à seguinte idéia básica, estará implementando o MVC:

  • Modelo: O que renderizar
  • Ver: Como processar
  • Controlador: Eventos, entrada do usuário

Pense também desta maneira: quando você programa seu modelo, ele não precisa se preocupar com a renderização (ou código específico da plataforma). O modelo diria para a visualização: não me importo se sua renderização for Android ou iOS ou Windows Phone, é isso que preciso que você renderize. A visualização trataria apenas o código de renderização específico da plataforma.

Isso é particularmente útil quando você usa o Mono para compartilhar o modelo e desenvolver aplicativos de plataforma cruzada.

Ramon Chan
fonte
12
Embora isso seja verdade, e bem colocado, isso é teoria e as pessoas são práticas!
TWIStErRob
1
@TWiStErRob Mas os padrões de design são idéias abstratas e teóricas que não têm apenas uma maneira de realizá-las. Proclamar “Eu não quero entender o MVC em teoria, só quero implementá-lo” me parece que poderia resultar em “Vou colocar uma máquina de lavar na minha cozinha porque as máquinas de lavar implementam o padrão Cleaner ™ e as cozinhas precisam disso ”.
Lucas
1
Penso que os exemplos são inestimáveis ​​porque mostram o que as outras pessoas criaram. Pode-se aperfeiçoá-los e aprender com seus esforços. Não é necessário que todos reinventem a roda. No contexto do Android e seu ciclo de vida complexo, existem problemas não abordados em um padrão de design, mas todos os enfrentarão. Isto é o que eu quis dizer com prático.
TWIStErRob
47

As ações, visualizações e atividades no Android são a maneira prática de trabalhar com a UI do Android e são uma implementação do padrão MVVM (model-view-viewmodel) , que é estruturalmente semelhante (na mesma família que) à visualização de modelo -controlador.

Que eu saiba, não há como sair desse modelo. Provavelmente, isso pode ser feito, mas você provavelmente perderia todos os benefícios que o modelo existente possui e teria que reescrever sua própria camada de interface do usuário para fazê-lo funcionar.

Derick Bailey
fonte
29

Após algumas pesquisas, a resposta mais razoável é a seguinte:

O MVC já está implementado no Android como:

  1. Ver = layout, recursos e classes Buttoninternas como derivadas android.view.View.
  2. Controlador = Atividade
  3. Modelo = as classes que implementam a lógica do aplicativo

(A propósito, isso não implica lógica de domínio de aplicativo na atividade.)

O mais razoável para um pequeno desenvolvedor é seguir esse padrão e não tentar fazer o que o Google decidiu não fazer.

PS Observe que, às vezes, a atividade é reiniciada, portanto, não há lugar para os dados do modelo (a maneira mais fácil de causar uma reinicialização é omitir android:configChanges="keyboardHidden|orientation"o XML e ativar o dispositivo).

EDITAR

Podemos estar falando sobre MVC , mas será o caso de FMVC , Framework - Model - View - Controller . O Framework (o sistema operacional Android) impõe sua idéia do ciclo de vida dos componentes e eventos relacionados e, na prática, o Controller ( Activity/ Service/ BroadcastReceiver) é o primeiro responsável por lidar com esses eventos impostos pelo Framework (como onCreate () ). A entrada do usuário deve ser processada separadamente? Mesmo que deva, você não pode separá-lo, os eventos de entrada do usuário também vêm do Android.

De qualquer forma, quanto menos código não for específico do Android você colocar no seu Activity/ Service/ BroadcastReceiver, melhor.

18446744073709551615
fonte
3
A atividade tem acesso direto à interface do usuário, enquanto no controlador MVC não deve saber sobre a exibição (apenas vice-versa).
Konrad Morawski
2
@KonradMorawski Hmmm .... Uma visão sabendo sobre a exibição de coisas e sobre o Controller ? Um filho, digamos, Buttonconhecedor do Controlador ? Parece mais lógico que o Views saiba apenas sobre a exibição de coisas. E levando em conta que o Model conhece apenas a natureza dos dados, é por isso que o Controller é necessário: algo deve conhecer tanto o Model quanto a View .
18446744073709551615
4
Obviamente, o View precisa saber sobre o controlador para delegar eventos ao controlador. O controlador segue até o modelo e informa a View quais foram os resultados (para que ele possa ser exibido). O controlador não inflaciona a exibição (enquanto o Activity o faz), nem deve saber nada sobre botões, caixas de texto, listas etc. (enquanto o Activity sabe).
Konrad Morawski
1
Eu acho que Services estão sob a égide do controlador também
CL22
1
Já ouviu falar de observadores? A melhor separação que Iv encontrou até agora é quando 1. o controlador possui apenas uma instância de modelo, 2. o modelo não tem conhecimento do controlador ou da visualização, mas a visualização pode se registrar como observador do modelo (portanto, o modelo meio que conhece a visualização, mas ele não sabe quem é e ele não se importa) - quando o modelo é concluído com o carregamento de dados, ele notifica todos os observadores (geralmente 1) e 3. o view tem apenas uma instância de modelo para extrair dados dele. Dessa forma, existem apenas 2 dependências para toda a estrutura MVC. Eu acho que 2 é mínimo, então deve ser o melhor layout.
precisa saber é o seguinte
18

Não há um padrão único de MVC ao qual você possa obedecer. O MVC apenas afirma mais ou menos que você não deve misturar dados e visualizações, de modo que, por exemplo, as visualizações sejam responsáveis ​​por manter dados ou classes que estão processando dados, afetando diretamente a visualização.

Mas, no entanto, da maneira como o Android lida com classes e recursos, às vezes você é forçado a seguir o padrão MVC. Mais complicadas, na minha opinião, são as atividades que às vezes são responsáveis ​​pela visão, mas, no entanto, atuam como controladoras ao mesmo tempo.

Se você definir suas visualizações e layouts nos arquivos XML, carregue seus recursos da pasta res e se evitar mais ou menos misturar essas coisas no seu código, estará seguindo um padrão MVC.

RoflcoptrException
fonte
14

Você pode implementar o MVC no Android, mas ele não é "suportado nativamente" e exige algum esforço.

Dito isso, eu pessoalmente tendem ao MVP como um padrão arquitetural muito mais limpo para o desenvolvimento do Android. E dizendo MVP, quero dizer o seguinte:

insira a descrição da imagem aqui

Também publiquei uma resposta mais detalhada aqui .

Depois de brincar com as várias abordagens para a implementação do MVC / MVP no Android, criei um padrão de arquitetura razoável, que descrevi neste post: MVP e MVC Architectural Patterns no Android .

Vasiliy
fonte
14

O melhor recurso que encontrei para implementar o MVC no Android é este post :

Eu segui o mesmo design para um dos meus projetos e funcionou muito bem. Eu sou iniciante no Android, então não posso dizer que esta é a melhor solução.

Fiz uma modificação: instanciei o modelo e o controlador para cada atividade na classe de aplicativo para que eles não sejam recriados quando o modo paisagem-retrato é alterado.

Hervé Donner
fonte
8
seria ótimo obter um resumo caso o artigo seja excluído um dia.
Pqsk 16/08
12

Eu concordo com o JDPeckham e acredito que apenas o XML não é suficiente para implementar a parte da interface do usuário de um aplicativo.

No entanto, se você considerar a Atividade como parte da visualização, a implementação do MVC é bastante direta. Você pode substituir o Aplicativo (conforme retornado por getApplication () na Atividade) e é aqui que você pode criar um controlador que sobrevive por toda a vida útil do seu aplicativo.

(Como alternativa, você pode usar o padrão singleton conforme sugerido pela documentação do aplicativo)

digitando
fonte
12

Arquitetura MVC- no Android É melhor seguir qualquer MVP do que MVC no Android. Mas ainda de acordo com a resposta à pergunta, isso pode ser solução

Digite a descrição da imagem aqui

Descrição e Diretrizes

     Controller -
        Activity can play the role.
        Use an application class to write the
        global methods and define, and avoid
        static variables in the controller label
    Model -
        Entity like - user, Product, and Customer class.
    View -
        XML layout files.
    ViewModel -
        Class with like CartItem and owner
        models with multiple class properties
    Service -
        DataService- All the tables which have logic
        to get the data to bind the models - UserTable,
        CustomerTable
        NetworkService - Service logic binds the
        logic with network call - Login Service
Helpers -
        StringHelper, ValidationHelper static
        methods for helping format and validation code.
SharedView - fragmets or shared views from the code
        can be separated here

AppConstant -
        Use the Values folder XML files
        for constant app level

NOTA 1:

Agora, aqui está a peça de mágica que você pode fazer. Depois de classificar o trecho de código, escreva uma classe de interface básica como IEntity e IService. Declarar métodos comuns. Agora crie a classe abstrata BaseService e declare seu próprio conjunto de métodos e faça uma separação de código.

NOTA 2: Se sua atividade estiver apresentando vários modelos, em vez de escrever o código / lógica na atividade, é melhor dividir as visualizações em fragmentos. Então é melhor. Portanto, no futuro, se for necessário exibir mais modelo na exibição, adicione mais um fragmento.

NOTA 3: A separação do código é muito importante. Todo componente da arquitetura deve ser independente, sem lógica dependente. Se por acaso você tiver alguma lógica dependente, escreva uma classe de lógica de mapeamento no meio. Isso o ajudará no futuro.

DropAndTrap
fonte
11

A criação da interface do usuário do Android usando layouts, recursos, atividades e intenções é uma implementação do padrão MVC. Consulte o link a seguir para obter mais informações sobre isso - http://www.cs.otago.ac.nz/cosc346/labs/COSC346-lab2.2up.pdf

espelho para o pdf

Arunabh Das
fonte
7
o link está quebrado senhor
Rat-a-tat-a-tat Ratatouille
2
Parece que este arquivo COSC346-lab2.2up.pdf não inclui detalhes completos.
james
9

O padrão MVC do Android é (mais ou menos) implementado com suas classes de adaptadores . Eles substituem um controlador por um "adaptador". A descrição para o adaptador declara:

Um objeto Adapter atua como uma ponte entre um AdapterView e os dados subjacentes para essa exibição.

Estou apenas pesquisando isso para um aplicativo Android que lê de um banco de dados, então ainda não sei como ele funciona. No entanto, parece um pouco com a arquitetura Model-View-Delegate da Qt, que eles afirmam ser um passo acima do padrão tradicional do MVC. Pelo menos no PC, o padrão do Qt funciona bastante bem.

Ben
fonte
9

Embora este post pareça antigo, gostaria de adicionar os dois a seguir para informar sobre o desenvolvimento recente nessa área para Android:

android-binding - Fornece uma estrutura que enraíza a ligação dos widgets da visualização android ao modelo de dados. Ajuda a implementar padrões MVC ou MVVM em aplicativos Android.

roboguice - o RoboGuice elimina as suposições do desenvolvimento. Injete seu modo de exibição, recurso, serviço do sistema ou qualquer outro objeto e deixe o RoboGuice cuidar dos detalhes.

Mahendra Liya
fonte
9

Controlador de visualização de modelo (MVC)

insira a descrição da imagem aqui


Descrição:

  • Quando temos que principais projetos grandes no desenvolvimento de software, o MVC geralmente é usado porque é uma maneira universal de organizar os projetos.
  • Novos desenvolvedores podem se adaptar rapidamente ao projeto
  • Auxilia no desenvolvimento de grandes projetos e também em várias plataformas.

O padrão MVC é essencialmente este:

  • Modelo: O que exibir. Pode ser a fonte de dados (por exemplo: servidor, dados brutos no aplicativo)
  • Ver: como é exibido. Este pode ser o xml. Está, portanto, atuando como um filtro de apresentação. Uma visão é anexada ao seu modelo (ou parte do modelo) e obtém os dados necessários para a apresentação.
  • Controlador: manipulando eventos como entrada do usuário. Essa é a atividade

Recurso importante do MVC: Podemos modificar o modelo, a visualização ou o controlador ainda não afetando os outros

  • Digamos que alteramos a cor na visualização, o tamanho da visualização ou a posição da visualização. Ao fazer isso, não afetará o modelo ou o controlador
  • Digamos que alteramos o modelo (em vez de os dados buscados no servidor buscarem dados dos ativos), mas isso não afetará a visualização e o controlador
  • Digamos que alteramos o controlador (lógica na atividade), isso não afetará o modelo e a visualização
Devrath
fonte
2
Eu só usei o controlador como um canal para saber como exibir / modelar informações de retransmissão. Estou curioso para saber como você tem modelo e visão em contato direto um com o outro. Você tem uma fonte ou exemplo desta implementação?
Jacksonkr
7

Eu acho que a explicação simplificada mais útil está aqui: http://www.cs.otago.ac.nz/cosc346/labs/COSC346-lab2.2up.pdf

De tudo o que vi e li aqui, implementar todas essas coisas torna mais difícil e não se encaixa bem com outras partes do Android.

Ter uma atividade implementando outros ouvintes já é a maneira padrão do Android. A maneira mais inofensiva seria adicionar o Java Observer como os slides descrevem e agrupar o onClick e outros tipos de ações em funções que ainda estão na Atividade.

A maneira do Android é que a Atividade faça as duas coisas. Lutar contra isso não facilita a extensão ou a codificação futura.

Eu concordo com o segundo post . Já está implementado, mas não do jeito que as pessoas estão acostumadas. Esteja ou não no mesmo arquivo ou não, já existe separação. Não é necessário criar uma separação extra para ajustá-lo a outros idiomas e sistemas operacionais.

Edmund Chang
fonte
6
O link que você forneceu está quebrado.
MMB
6

Foi surpreendente ver que nenhuma das postagens aqui respondeu à pergunta. Eles são muito gerais, vagos, incorretos ou não abordam a implementação no Android.

No MVC, a camada Exibir sabe apenas como mostrar a interface do usuário (UI). Se algum dado for necessário para isso, ele será obtido na camada Modelo . Mas o View NÃO solicita diretamente ao modelo que encontre os dados, ele o faz através do Controller . Portanto, o Controlador  chama o Modelo para fornecer os dados necessários para a Visualização . Quando os dados estiverem prontos, o Controlador informará à Visualização que os dados estão prontos para serem adquiridos do Modelo . Agora o View pode obter os dados do modelo .

Esse fluxo pode ser resumido como abaixo:

insira a descrição da imagem aqui

É importante notar que o View pode saber sobre a disponibilidade dos dados no  Modelo  através do Controller - também conhecido como  Passive MVC - ou observando os dados no Model registrando observáveis ​​nele, que é o Active MVC .

Na parte de implementação, uma das primeiras coisas que vem à mente é que qual componente do Android deve ser usado para o View ? Activity  ou Fragment ?

A resposta é que isso não importa e ambos podem ser usados. O modo de exibição deve poder apresentar a interface do usuário (UI) no dispositivo e responder à interação do usuário com a interface do usuário. Ambos Activity  e Fragment  fornecem os métodos necessários para isso.

No aplicativo de exemplo usado neste artigo , usei Activity a camada View , mas Fragment  também pode ser usada.

O aplicativo de exemplo completo pode ser encontrado na ramificação 'mvc' do meu repositório GitHub aqui .

Eu também lidei com os prós e contras da arquitetura MVC no Android através de um exemplo aqui .

Para os interessados, eu comecei uma série de artigos sobre arquitetura android aplicativo aqui em que eu comparar as diferentes arquiteturas, ou seja, MVC, MVP, MVVM, para desenvolvimento de aplicativos Android através de um aplicativo de trabalho completo.

Ali Nem
fonte
Fiz um curso de arquitetura em que o instrutor afirma que atividades e fragmentos não devem ser usados ​​como visualizações e, de fato, devem ser controladores e que as visualizações devem ser arquivos separados. Você tem alguma opinião ou raciocínio sobre por que isso não deveria acontecer?
brandonx
Eu não acho que o instrutor seja preciso nisso. Escolher atividade ou fragmento como controlador significa passar o contexto para o controlador. Por outro lado, a vista também precisa de contexto para desenhar na tela. Dessa forma, ou seja, passar o contexto para o controlador, torna o aplicativo propenso a vazamento de memória e acredito que o controlador não deve carregar o estado.
Ali Nem
5

Cansado do desastre do MVx no Android, criei recentemente uma pequena biblioteca que fornece fluxo de dados unidirecional e é semelhante ao conceito de MVC: https://github.com/zserge/anvil

Basicamente, você tem um componente (atividade, fragmento e grupo de visualizações). Dentro de você define a estrutura e o estilo da camada de vista. Além disso, você define como os dados devem ser vinculados às visualizações. Por fim, você pode vincular ouvintes no mesmo local.

Depois, quando seus dados forem alterados - o método global "render ()" será chamado e suas visualizações serão atualizadas de maneira inteligente com os dados mais recentes.

Aqui está um exemplo do componente que tem tudo para compactação de código (é claro que Model e Controller podem ser facilmente separados). Aqui "count" é um modelo, o método view () é uma view e "v -> count ++" é um controlador que escuta o botão clica e atualiza o modelo.

public MyView extends RenderableView {
  public MyView(Context c) {
      super(c);
  }

  private int count = 0;

  public void view() {
    frameLayout(() -> {              // Define your view hierarchy
      size(FILL, WRAP);
      button(() -> {
          textColor(Color.RED);      // Define view style
          text("Clicked " + count);  // Bind data
          onClick(v -> count++);     // Bind listeners
      });
    });
  }

Com o modelo e o controlador separados, seria semelhante a:

button(() -> {
   textColor(Color.RED);
   text("Clicked " + mModel.getClickCount());
   onClick(mController::onButtonClicked);
});

Aqui em cada botão, o número será aumentado, então "render ()" será chamado e o texto do botão será atualizado.

A sintaxe se torna mais agradável se você usar o Kotlin: http://zserge.com/blog/anvil-kotlin.html . Além disso, há uma sintaxe alternativa para Java sem lambdas.

A biblioteca em si é muito leve, não possui dependências, não usa reflexão, etc.

(Aviso: sou o autor desta biblioteca)

zserge
fonte
4

De acordo com a explicação que a equipe do Xamarin explicou (no iOS MVC "eu sei que parece estranho, mas espere um segundo"):

  • O modelo (lógica de dados ou aplicativo),
  • A visualização (interface do usuário) e
  • O controlador (código atrás).

Eu posso dizer o seguinte:

O modelo no Android é simplesmente o objeto parcelável. A visualização é o layout XML e o controlador é a (atividade + seu fragmento).

* Esta é apenas a minha opinião, não de qualquer recurso ou livro.

zaPlayer
fonte
4

Não existe uma arquitetura MVC implementada, mas existe um conjunto de bibliotecas / exemplos para implementar uma arquitetura MVP (model-view-apresentador).

Por favor, verifique estes links:

O Google adicionou um exemplo de MVP de arquitetura Android:

carlos.baez
fonte
3

Vi que muitas pessoas estão dizendo que o MVC já está implementado no Android, mas não é verdade. O Android não segue MVC por padrão.

Como o Google nunca impõe com força as restrições de uma implementação MVC como o iPhone, mas depende dos desenvolvedores quais padrões ou técnicas eles desejam em seu projeto. Em aplicativos pequenos ou simples, o uso do MVC não é necessário, mas como o aplicativo cresce e se torna complicado e exige modificações de seu código nos últimos anos, então é necessário o padrão MVC no Android.

Ele fornece uma maneira fácil de modificar o código e também ajuda na redução de problemas. Se você deseja implementar o MVC no Android, siga este link abaixo e aproveite a implementação do MVC em seu projeto.

http://www.therealjoshua.com/2011/11/android-architecture-part-1-intro/

Mas hoje em dia acho que o MVP, juntamente com o Android Architectural Pattern, é uma das melhores opções que os desenvolvedores devem usar para aplicativos Android limpos e robustos.

Lana Rana
fonte
1
Acordado. O Android tem flexibilidade suficiente para se enforcar. Essa atividade pode rapidamente se tornar gigantesca e complicada, pois lida com os três aspectos do MVC.
Scott Biggs
2

Quando aplicamos o MVC, MVVM ou Modelo de Apresentação a um aplicativo Android, o que realmente queremos é ter um projeto estruturado claro e, mais importante, mais fácil para testes de unidade.

No momento, sem uma estrutura de terceiros, você normalmente possui muitos códigos (como addXXListener (), findViewById () etc.), que não agregam valor comercial.

Além disso, você precisa executar testes de unidade Android em vez de testes JUnit normais, que levam anos para serem executados e tornam os testes unitários um pouco impraticáveis. Por esses motivos, alguns anos atrás, começamos um projeto de código aberto, RoboBinding - Uma estrutura de modelo de apresentação de ligação de dados para a plataforma Android.

O RoboBinding ajuda a escrever um código de interface do usuário mais fácil de ler, testar e manter. O RoboBinding elimina a necessidade de código desnecessário, como o addXXListener , e muda a lógica da interface do usuário para o Presentation Model, que é um POJO e pode ser testado através de testes JUnit normais . O próprio RoboBinding vem com mais de 300 testes JUnit para garantir sua qualidade.

Cheng
fonte
1

No meu entendimento, a maneira como o Android lida com o padrão MVC é como:

Você tem uma atividade, que serve como controlador. Você tem uma classe cuja responsabilidade é obter os dados - o modelo e, em seguida, a classe View, que é a visualização.

Ao falar sobre a visualização, a maioria das pessoas pensa apenas na parte visual definida no xml. Não devemos esquecer que o View também possui uma parte do programa com seus construtores, métodos e etc, definidos na classe java.

Rados
fonte