Modello MVC su Android


497

È possibile implementare il modello di modello vista-controller in Java per Android?

O è già implementato tramite Attività? O c'è un modo migliore per implementare il modello MVC per Android?


64
La tua domanda è molto buona Ma la risposta contrassegnata come soluzione non è corretta secondo me. Potrebbe sbagliare diverse persone.
Saghar,

4
Dai un'occhiata ai miei 2 post a partire da Android Architecture: MV?
Dori,

1
Esiste anche un ulteriore set di regole da seguire per aderire a MVC o lo sviluppo di Android è già su misura per MVC a causa di attività, XML, risorse?
Fiamma di udun,

3
@Dori, risolto il tuo link: Android Architecture: MV?
Andreybeta,

Questo articolo corrisponde esattamente a quello che stai cercando, MVC in Android attraverso un esempio pratico: digigene.com/architecture/android-architecture-part-2-mvc
Ali Nem

Risposte:


239

In Android non hai MVC, ma hai i seguenti:


3
@JDPekham, perché dici "Non puoi creare un'istanza di un'attività senza parlare con il tuo layout / vista"? L'istanza di un'attività non richiede la conversazione con le viste, in effetti parlare con le viste non fa assolutamente parte dell'istanza di Attività. Puoi (ma non è necessario) chiamare vari metodi di attività che interagiscono con le tue viste quando e se ritieni opportuno. Seconda domanda: supponendo che l'attività abbia lo scopo di assumere il ruolo di "controller" (credo che molti sviluppatori Android lo vedano in questo modo) perché non parlare delle tue opinioni dall'attività?

8
Per chiunque dica che "Android è MVC", prova Backbone.js (sì, lato client js) per una settimana, quindi torna indietro e dì che "Android è MVC". Finalmente capirai la domanda e perché continuiamo a chiedere :)
Mark Peterson,

14
"In Android non hai MVC" ???? In Android, come in altre lingue, hai MVC se vuoi MVC.
Lorenzo Barbagli,

1
@LorenzoBarbagli Intende, Android non impone MVC nelle app in base alla progettazione (come fa iOS). Devi implementare tu stesso un MVC, MVP o qualcos'altro se vuoi ottenere ciò che MVC fornisce - vale a dire la separazione delle preoccupazioni e un modello isolato e facilmente testabile.
Piovezan,

No. C'è sicuramente MVC su Android, ma più implicitamente. È appena implementato in un modo diverso per come Android struttura tutto.
6rchid

229

Non esiste un modello MVC universalmente unico. MVC è un concetto piuttosto che un solido framework di programmazione. Puoi implementare il tuo MVC su qualsiasi piattaforma. Finché ti attieni alla seguente idea di base, stai implementando MVC:

  • Modello: cosa rendere
  • Visualizza: come eseguire il rendering
  • Controller: eventi, input dell'utente

Pensaci anche in questo modo: quando programmi il tuo modello, il modello non dovrebbe preoccuparsi del rendering (o del codice specifico della piattaforma). Il modello direbbe alla vista, non mi interessa se il tuo rendering è Android o iOS o Windows Phone, questo è quello che mi serve per renderizzare. La vista gestirà solo il codice di rendering specifico della piattaforma.

Ciò è particolarmente utile quando si utilizza Mono per condividere il modello al fine di sviluppare applicazioni multipiattaforma.


12
Sebbene sia vero, e ben detto, questa è teoria e le persone sono pratiche!
TWiStErRob,

1
@TWiStErRob Ma i modelli di progettazione sono idee teoriche e astratte che non hanno solo un modo per realizzarle. Proclamare che "Non voglio capire MVC in teoria, voglio solo averlo implementato" mi suona come se potesse portare a "Metterò una lavatrice nella mia cucina perché le macchine implementano il modello Cleaner ™ e le cucine ne hanno bisogno ”.
Lukas Juhrich,

1
Penso che gli esempi siano inestimabili perché mostrano ciò che altre persone hanno escogitato. Si può migliorare su di loro e imparare dai loro sforzi. Non è necessario che tutti reinventino la ruota. Nel contesto di Android e del suo ciclo di vita complesso ci sono problemi non affrontati in un modello di progettazione, ma tutti li affronteranno. Questo è ciò che intendevo per pratico.
TWiStErRob

47

Le azioni, le viste e le attività su Android sono il modo di lavorare con l'interfaccia utente Android e sono un'implementazione del modello modello-view-viewmodel (MVVM) , che è strutturalmente simile (nella stessa famiglia di) modello-vista -Controller.

Per quanto ne so, non c'è modo di uscire da questo modello. Probabilmente può essere fatto, ma probabilmente perderai tutti i vantaggi del modello esistente e dovrai riscrivere il tuo livello UI per farlo funzionare.


29

Dopo alcune ricerche, la risposta più ragionevole è la seguente:

MVC è già implementato in Android come:

  1. Visualizza = layout, risorse e classi integrate come Buttonderivate android.view.View.
  2. Controller = Attività
  3. Modello = le classi che implementano la logica dell'applicazione

(A proposito, ciò non implica alcuna logica del dominio dell'applicazione nell'attività.)

La cosa più ragionevole per un piccolo sviluppatore è seguire questo schema e non provare a fare ciò che Google ha deciso di non fare.

PS Si noti che a volte l'attività viene riavviata, quindi non è disponibile per i dati del modello (il modo più semplice per causare un riavvio è omettere android:configChanges="keyboardHidden|orientation"l'XML e girare il dispositivo).

MODIFICARE

Potremmo parlare di MVC , ma sarà per così dire FMVC , Framework - Model - View - Controller . Il Framework (il sistema operativo Android) impone la sua idea del ciclo di vita dei componenti e degli eventi correlati, e in pratica il Controller ( Activity/ Service/ BroadcastReceiver) è innanzitutto responsabile della gestione di questi eventi proposti dal Framework (come onCreate () ). L'input dell'utente deve essere elaborato separatamente? Anche se dovrebbe, non è possibile separarlo, anche gli eventi di input dell'utente provengono da Android.

Comunque, meno codice non specifico per Android viene inserito nel Activity/ Service/ BroadcastReceiver, meglio è.


3
L'attività ha accesso diretto all'interfaccia utente, mentre nel controller MVC non è necessario conoscere la vista (solo viceversa).
Konrad Morawski,

2
@KonradMorawski Hmmm .... Una vista sapendo sulla visualizzazione delle cose e sul controller ? Un bambino, diciamo, a Buttonconoscenza del controller ? Sembra più logico che Views sappia solo come visualizzare le cose. E tenendo conto del fatto che il Modello conosce solo la natura dei dati, ecco perché è necessario il Controller : qualcosa deve sapere sia sul Modello che sulla Vista .
18446744073709551615

4
Ovviamente il View deve conoscere il controller per delegare gli eventi al controller. Il controller lo segue fino al modello e informa il View quali erano i risultati (in modo che possa visualizzarlo). Il controller non gonfia la vista (mentre Attività lo fa), né dovrebbe sapere qualcosa su pulsanti, caselle di testo, elenchi ecc. (Mentre Attività lo sa).
Konrad Morawski,

1
Penso che anche io sia Servicesotto l'ombrello del controller
CL22,

1
Hai mai sentito parlare di osservatori? La migliore separazione che Iv ha trovato finora è quando 1. il controller ha solo un'istanza del modello, 2. il modello non ha conoscenza del controller o della vista ma la vista può registrarsi come osservatore del modello (quindi il modello è un po 'consapevole della vista ma non sa chi è e lui non importa) - quando il modello ha finito con il caricamento dei dati, avvisa tutti gli osservatori (di solito 1) e 3. view ha solo un'istanza del modello per estrarre i dati da esso. In questo modo ci sono solo 2 dipendenze per tutto il framework MVC. Penso che 2 sia il minimo, quindi dovrebbe essere il layout migliore.
Srneczek,

18

Non esiste un singolo modello MVC a cui potresti obbedire. MVC afferma solo più o meno che non dovresti mescolare dati e viste, quindi ad esempio le viste sono responsabili del mantenimento dei dati o delle classi che elaborano i dati influiscono direttamente sulla vista.

Tuttavia, nel modo in cui Android gestisce classi e risorse, a volte sei persino costretto a seguire il modello MVC. A mio avviso, sono più complicate le attività che a volte sono responsabili della vista, ma allo stesso tempo fungono da controller.

Se definisci le viste e i layout nei file XML, carichi le risorse dalla cartella res e se eviti più o meno di mescolare queste cose nel tuo codice, segui comunque un modello MVC.


14

Puoi implementare MVC in Android, ma non è "supportato nativamente" e richiede un certo sforzo.

Detto questo, personalmente tendo verso MVP come un modello architettonico molto più pulito per lo sviluppo di Android. E dicendo MVP intendo questo:

inserisci qui la descrizione dell'immagine

Ho anche pubblicato una risposta più dettagliata qui .

Dopo aver giocato con i vari approcci all'implementazione MVC / MVP in Android, ho trovato un modello architettonico ragionevole, che ho descritto in questo post: MVP e MVC Architectural Patterns in Android .


14

La migliore risorsa che ho trovato per implementare MVC su Android è questo post :

Ho seguito lo stesso design per uno dei miei progetti e ha funzionato alla grande. Sono un principiante su Android, quindi non posso dire che questa sia la soluzione migliore.

Ho apportato una modifica: ho creato un'istanza del modello e del controller per ciascuna attività nella classe dell'applicazione in modo che non vengano ricreati quando cambia la modalità orizzontale-verticale.


8
sarebbe bello ottenere un riepilogo nel caso in cui l'articolo venga eliminato un giorno.
pqsk,

12

Sono d'accordo con JDPeckham e credo che il solo XML non sia sufficiente per implementare la parte dell'interfaccia utente di un'applicazione.

Tuttavia, se si considera l'attività come parte della vista, l'implementazione di MVC è piuttosto semplice. Puoi sovrascrivere l' applicazione (come restituita da getApplication () in Attività) ed è qui che puoi creare un controller che sopravvive per la durata della tua applicazione.

(In alternativa è possibile utilizzare il modello singleton come suggerito dalla documentazione dell'applicazione)


12

MVC- Architecture su Android È meglio seguire qualsiasi MVP invece MVC in Android. Ma ancora secondo la risposta alla domanda questa può essere una soluzione

Inserisci qui la descrizione dell'immagine

Descrizione e linee guida

     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:

Ora ecco il pezzo di magia che puoi fare. Dopo aver classificato il pezzo di codice, scrivere una classe di interfaccia di base come IEntity e IService. Dichiarare metodi comuni. Ora crea la classe astratta BaseService e dichiara il tuo set di metodi e separa il codice.

NOTA 2: se l'attività presenta più modelli, anziché scrivere il codice / la logica in attività, è meglio dividere le viste in frammenti. Allora è meglio. Pertanto, in futuro, se è necessario visualizzare altri modelli nella vista, aggiungere un altro frammento.

NOTA 3: la separazione del codice è molto importante. Ogni componente nell'architettura dovrebbe essere indipendente senza logica dipendente. Se per caso se hai qualcosa di logico dipendente, allora scrivi una classe di logica di mappatura tra. Questo ti aiuterà in futuro.



9

Il modello MVC di Android è (tipo di) implementato con le loro classi Adapter . Sostituiscono un controller con un "adattatore". La descrizione per l'adattatore afferma:

Un oggetto Adapter funge da ponte tra un AdapterView e i dati sottostanti per quella vista.

Sto solo cercando questo per un'applicazione Android che legge da un database, quindi non so ancora come funzioni. Tuttavia, sembra un po 'come l'architettura Model-View-Delegate di Qt, che sostengono sia un passo avanti rispetto a un modello MVC tradizionale. Almeno sul PC, il modello di Qt funziona abbastanza bene.


9

Anche se questo post sembra essere vecchio, vorrei aggiungere i seguenti due per informare del recente sviluppo in quest'area per Android:

Android-binding : fornire un framework che abilita l'associazione dei widget di visualizzazione Android al modello di dati. Aiuta a implementare modelli MVC o MVVM in applicazioni Android.

roboguice - RoboGuice elimina le congetture dallo sviluppo. Iniettare la vista, la risorsa, il servizio di sistema o qualsiasi altro oggetto e lasciare che RoboGuice si occupi dei dettagli.


9

Model View Controller (MVC)

inserisci qui la descrizione dell'immagine


Descrizione:

  • Quando dobbiamo realizzare grandi progetti nello sviluppo del software, MVC viene generalmente utilizzato perché è un modo universale di organizzare i progetti.
  • I nuovi sviluppatori possono adattarsi rapidamente al progetto
  • Aiuta a sviluppare grandi progetti e anche multipiattaforma.

Il modello MVC è essenzialmente questo:

  • Modello: cosa visualizzare. Questa può essere l'origine dati (ad es. Server, dati non elaborati nell'app)
  • Visualizza: come viene visualizzato. Questo può essere l'xml. Funziona quindi come filtro di presentazione. Una vista è allegata al suo modello (o parte del modello) e ottiene i dati necessari per la presentazione.
  • Controller: gestione di eventi come l'input dell'utente. Questa è l'attività

Funzionalità importante di MVC: possiamo modificare il modello o la vista o il controller senza influire sugli altri

  • Supponiamo di cambiare il colore nella vista, le dimensioni della vista o la posizione della vista. In questo modo non influirà sul modello o sul controller
  • Supponiamo di cambiare il modello (invece di recuperare i dati dal server recuperare i dati dagli asset) ma ciò non influirà sulla vista e sul controller
  • Supponiamo che modifichiamo il Controller (logica nell'attività) che non influirà sul modello e sulla vista

2
Ho sempre usato il controller come condotto per visualizzare / inoltrare informazioni sul modello. Sono curioso di sapere come hai una modella e una vista a diretto contatto l'una con l'altra. Hai una fonte o un esempio di questa implementazione?
Jacksonkr,

7

Penso che la spiegazione semplificata più utile sia qui: http://www.cs.otago.ac.nz/cosc346/labs/COSC346-lab2.2up.pdf

Da tutto ciò che ho visto e letto qui, implementare tutte queste cose rende più difficile e non si adatta bene con altre parti di Android.

Avere un'attività implementare altri ascoltatori è già il modo Android standard. Il modo più innocuo sarebbe quello di aggiungere Java Observer come le diapositive descrivono e raggruppano onClick e altri tipi di azioni in funzioni ancora presenti nell'attività.

Il modo Android è che l'attività fa entrambe le cose. Combattere non rende davvero più semplice l'estensione o la codifica futura.

Sono d'accordo con il 2 ° post . È un po 'già implementato, ma non nel modo in cui le persone sono abituate. Indipendentemente dal fatto che sia o meno nello stesso file, esiste già una separazione. Non è necessario creare ulteriore separazione per adattarlo ad altre lingue e sistemi operativi.


6
Il link che hai fornito è interrotto.
mmB

6

È stato sorprendente vedere che nessuno dei post qui ha risposto alla domanda. Sono troppo generici, vaghi, errati o non affrontano l'implementazione in Android.

In MVC, il livello Visualizza sa solo come mostrare l'interfaccia utente (UI). Se sono necessari dati per questo, li ottiene dal livello Modello . Ma la vista NON richiede direttamente al modello di trovare i dati, ma lo fa attraverso il controller . Pertanto, il controller  chiama il modello per fornire i dati richiesti per la vista . Quando i dati sono pronti, il Titolare informa la Vista che i dati sono pronti per essere acquisiti dal Modello . Ora la vista può ottenere i dati dal modello .

Questo flusso può essere riassunto come di seguito:

inserisci qui la descrizione dell'immagine

Vale la pena notare che la Vista può conoscere la disponibilità dei dati nel  Modello  tramite Controller - noto anche come  MVC passivo - o osservando i dati nel Modello registrando osservabili su di esso, che è MVC attivo .

Per quanto riguarda l'implementazione, una delle prime cose che viene in mente è che quale componente Android dovrebbe essere usato per la vista ? Activity  o Fragment ?

La risposta è che non importa ed entrambi possono essere usati. La vista dovrebbe essere in grado di presentare l'interfaccia utente (UI) sul dispositivo e rispondere all'interazione dell'utente con l'interfaccia utente. Entrambi Activity  e Fragment  forniscono i metodi richiesti per questo.

Nell'app di esempio utilizzata in questo articolo ho usato Activity per il livello Visualizza , ma Fragment  può anche essere usato.

L'app di esempio completa è disponibile nel ramo 'mvc' del mio repository GitHub qui .

Ho anche trattato i pro e i contro dell'architettura MVC in Android attraverso un esempio qui .

Per coloro che sono interessati, ho iniziato una serie di articoli sull'architettura delle app Android qui in cui confronto le diverse architetture, ad esempio MVC, MVP, MVVM, per lo sviluppo di app Android attraverso un'app funzionante completa.


Ho seguito un corso di architettura in cui l'istruttore afferma che le attività e i frammenti non dovrebbero essere usati come viste e che in realtà dovrebbero essere controllori e le viste dovrebbero essere file separati. Hai qualche opinione o ragionamento sul perché questo non dovrebbe essere?
brandonx,

Non credo che l'istruttore sia preciso su questo. Scegliere attività o frammento come controller significa passare il contesto al controller. D'altra parte, la visualizzazione richiede anche un contesto per disegnare sullo schermo. In questo modo, vale a dire passare il contesto al controller, rende l'app soggetta a perdita di memoria e credo che il controller non debba riportare lo stato.
Ali Nem,

5

Essendo stanco del disastro MVx su Android, di recente ho creato una piccola libreria che fornisce un flusso di dati unidirezionale ed è simile al concetto di MVC: https://github.com/zserge/anvil

Fondamentalmente, hai un componente (attività, frammento e viewgroup). All'interno si definisce la struttura e lo stile del livello vista. Inoltre si definisce come i dati devono essere associati alle viste. Infine, puoi associare gli ascoltatori nello stesso posto.

Quindi, una volta modificati i dati, verrà chiamato il metodo globale "render ()" e le visualizzazioni verranno aggiornate in modo intelligente con i dati più recenti.

Ecco un esempio del componente che contiene tutto per la compattezza del codice (ovviamente Model e Controller possono essere facilmente separati). Qui "count" è un modello, view () è una vista e "v -> count ++" è un controller che ascolta i clic sui pulsanti e aggiorna il modello.

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
      });
    });
  }

Con il modello e il controller separati sembrerebbe:

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

Qui su ogni pulsante fare clic sul numero verrà aumentato, quindi verrà chiamato "render ()" e il testo del pulsante verrà aggiornato.

La sintassi diventa più piacevole se usi Kotlin: http://zserge.com/blog/anvil-kotlin.html . Inoltre, esiste una sintassi alternativa per Java senza lambdas.

La libreria stessa è molto leggera, non ha dipendenze, non usa riflessioni, ecc.

(Dichiarazione di non responsabilità: sono l'autore di questa biblioteca)


4

Secondo la spiegazione spiegata dal team Xamarin (su iOS MVC "So che sembra strano, ma aspetta un secondo"):

  • Il modello (dati o logica dell'applicazione),
  • La vista (interfaccia utente) e
  • Il controller (codice dietro).

Posso dire questo:

Il modello su Android è semplicemente l'oggetto parcelable. La vista è il layout XML e il controller è (attività + il suo frammento).

* Questa è solo la mia opinione, non da nessuna risorsa o da un libro.



3

Ho visto che molte persone stanno dicendo che MVC è già implementato in Android, ma non è vero. Android non segue MVC per impostazione predefinita.

Perché io non Google imporrò mai con forza le restrizioni di un'implementazione MVC come iPhone, ma spetta agli sviluppatori quale modello o tecnica vogliono nel loro progetto, nelle applicazioni piccole o semplici non è richiesto l'uso di MVC, ma come l'applicazione cresce e diventa complicato e richiede modifiche del suo codice negli anni successivi, quindi arriva la necessità del modello MVC in Android.

Fornisce un modo semplice per modificare il codice e aiuta anche a ridurre i problemi. Se desideri implementare MVC su Android, segui questo link indicato di seguito e goditi l'implementazione MVC nel tuo progetto.

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

Ma al giorno d'oggi penso che MVP insieme ad Android Architectural Pattern sia una delle migliori opzioni che gli sviluppatori dovrebbero usare per applicazioni Android pulite e robuste.


1
Concordato. Android ha abbastanza flessibilità per impiccarti. Quell'attività può diventare rapidamente gigantesca e complicata poiché gestisce tutti e tre gli aspetti di MVC.
Scott Biggs,

2

Quando applichiamo MVC, MVVM o il modello di presentazione a un'app Android, ciò che vogliamo davvero è avere un progetto chiaro e strutturato e, soprattutto, più semplice per i test unitari.

Al momento, senza un framework di terze parti, di solito hai un sacco di codice (come addXXListener (), findViewById (), ecc.), Che non aggiunge alcun valore aziendale.

Inoltre, devi eseguire i test unitari Android anziché i normali test JUnit, che richiedono anni per essere eseguiti e rendere i test unitari piuttosto impraticabili. Per questi motivi, alcuni anni fa abbiamo avviato un progetto open source, RoboBinding - Un framework per modelli di presentazione vincolante i dati per la piattaforma Android.

RoboBinding ti aiuta a scrivere codice UI che è più facile da leggere, testare e gestire. RoboBinding elimina la necessità di codice non necessario come addXXListener o giù di lì , e sposta la logica dell'interfaccia utente sul modello di presentazione, che è un POJO e può essere testato tramite normali test JUnit . RoboBinding stesso viene fornito con oltre 300 test JUnit per garantirne la qualità.


1

A mio avviso, il modo in cui Android gestisce il modello MVC è come:

Hai un'attività, che funge da controller. Hai una classe che ha la responsabilità di ottenere i dati - il modello, e poi hai la classe View che è la vista.

Quando si parla della vista, la maggior parte delle persone pensa solo per la sua parte visiva definita nell'xml. Non dimentichiamo che View ha anche una parte di programma con i suoi costruttori, metodi ed ecc, definiti nella classe java.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.